שלוט במאסטר Import-Csv ופקודות CSV אחרות ב-PowerShell

הַ cmdlet Export-Csv ב-PowerShell וה-cmdlet Import-Csv ב-PowerShell מאפשרים למנהלים לייבא CSVs דרך לולאת foreach, להשתמש ב-Export-Csv כדי להוסיף CSVs ולייצא מערכות לקובץ CSV ועוד הרבה יותר.

במאמר זה תלמד על התרחשויות נפוצות בהן תוכל להשתמש ב-PowerShell כדי לנהל CSVs כמו:

  • קריאת קבצי CSV עם PowerShell
  • שמירת קבצי CSV עם PowerShell
  • עיצוב הפלט לפני הפעלת Export-CSV
  • הוספת נתונים ל-CSV
  • הוספת שונויות לקובץ קיים
  • Export-CSV והמחרוזת #TYPE

אם אתה לא מכיר את הפעולות הפנימיות של קבצי CSV, הם קבצי טקסט העוקבים אחר פורמט סטנדרטי של הפרדת ערכים בטבלה באמצעות פסיק. תוכל ליצור קובץ CSV ב-PowerShell באמצעות ה-cmdlet Export-Csv ולהעביר אליו אובייקט או יותר.

הפקודה למטה מוצאת את שני התוכניות הרצות הראשונות ומעבירה את האובייקטים שנוצרו ל-cmdlet Export-Csv. ה-cmdlet Export-Csv יוצר אז קובץ CSV בשם processes.csv בשורש הדיסק המערכת שלך (בכל זאת, כנראה C:\).

PS51> Get-Process | Select-Object -First 2 | Export-CSV -Path "$env:SystemDrive\processes.csv"

עכשיו פתחו את processes.csv עם Notepad. תראו את "Name","SI","Handles","VM" בראש ככותרות. תראו גם את #TYPE System.Diagnostics.Process, שייתכן שלא יהיה הרבה משמעות עכשיו. אל תדאגו, אנחנו נכסה את המחרוזת הזו במאמר זה.

קריאת קבצי CSV עם Import-Csv

רוצים עוד טיפים כאלה? בדקו את הבלוג האישי שלי ב- PowerShell

פוורשל יש כמה פקודות שמאפשרות לך לקרוא קבצי טקסט. הפקודות הללו הן Get-Content ו־Import-Csv. כל אחת מהפקודות האלה קוראת בפועל את הקובץ באותה הדרך. אבל Import-Csv עושה צעד נוסף. Import-Csv מבין את המבנה התחתון לא רק של קובץ טקסט אלא של קובץ CSV.

מאחר וקובץ CSV עוקב אחר סכימה מסוימת, Import-Csv מבין את סכימת ה-CSV. פקודה זו לא קוראת רק את הקובץ הטקסט מהדיסק אלא גם ממירה את השורות בקובץ ה-CSV לאובייקטים בפוורשל.

קבצים לא CSV

לרוב, המידע ב-CSV מופרד באמצעות פסיקים, אך ישנם פעמים שבהן CSV (לא באופן טכני CSV בנקודה זו) מכיל מידע שמופרד באמצעות מפריד אחר. המפרידים האלה הם לעיתים תו טאב או אולי נקודה ופסיק.

אם יש לך CSV עם גורם תיאור שונה, תוכל להשתמש בפרמטר Delimiter. פרמטר זה מגיד ל-Import-Csv לא לחפש פסיקים, שזו הערך המוגדר כברירת מחדל, אלא לחפש ערך אחר.

לדוגמה, אם יש לך קובץ המופרד בלוחות, תוכל לקרוא את הקובץ כך:

PS51> Import-Csv -Path tab-separated-data.csv -Delimiter "`t"

הוספת כותרות

A common Import-Csv parameter is Header. This parameter lets you specify the property names of the objects created by this cmdlet.

כברירת מחדל, פקודת ה-Import-Csv מטפלת בשורה העליונה של קובץ ה-CSV ככותרות. היא ממירה את הערכים שבשורה זו למאפיינים של כל שורה (אובייקט). אבל אם יש לך קובץ CSV שאין לו שורת כותרת, תוכל להשתמש בפרמטר Header כדי להגדיר כותרת בעצמך.

הפרמטר Header מונע מ-Import-CSV להשתמש בשורה הראשונה ככותרת וגם חוסך לך טירוף מהצורך לפתוח את קובץ ה-CSV באופן ידני כדי להוסיף כותרות בעצמך.

כדי להדגים את התנהגות זו, פתח את המחברת והעתק/הדבק את הטקסט הבא. הטקסט יייצג סט נתונים עם שלוש שורות ושני עמודות.

a,1
b,2
c,3

שמור את קובץ הטקסט כ-test.csv. אל תשכח לאפשר סיומות קובץ או להקפיד להקיף את שם הקובץ בגרשיים כדי לא לשמור אותו במקרה ויש סיומת .csv.txt לא רצויה!

עכשיו, השתמש ב-Import-CSV כדי לקרוא את קובץ ה-CSV שנוצר לאחרונה בלעדי פרמטר ה-Header ובדוק את הפלט.

PS51> Import-Csv .\test.csv

a 1
---
b 2
c 3

שים לב שהשורה הראשונה הופכת לפרות המאפיינים של העצם. `A` ו־`1` אינם "תוויות" שברצונך לקבוע עבור פרות המאפיינים. `A`, `b` ו־`c` הם אותיות בעוד `1`, `2` ו־`3` הם מספרים. עליך להגדיר את אלו בעזרת פרמטר `Header` כמו שמוצג למטה:

PS51> Import-Csv .\test.csv -Header "Letter", "Number"

Letter Number
------ ------
a      1
b      2
c      3

שמירת קבצי CSV בעזרת PowerShell

אם נדרש ליצור או לשמור קובץ CSV מאובייקטים של PowerShell, ניתן גם לעשות זאת בדרך אחרת. בעוד ש־Import-Csv ממיר קובץ CSV לאובייקטים של PowerShell, Export-Csv עושה את ההפך. פקודת ה־Export-Csv ממירה אובייקטים של PowerShell לקובץ CSV.

על ידי שמירת קובץ CSV עם Export-Csv ניתן לך לצפות או להשתמש בנתונים אלה במערכות אחרות מאוחר יותר.

לדוגמה, אני יכול לשמור את כל התהליכים הרצים במחשב שלי על ידי הניתוב של Get-Process ל־Export-Csv.

PS51> Get-Process | Export-Csv -Path processes.csv

פקודת ה־Export-Csv פשוטה מבחינת מבנה, אך ישנם כמה דברים שצריך להיות זהיר בנוגע אליה.

עיצוב הפלט לפני הרצת Export-CSV

כפי שראית כאן למעלה, Export-Csv, לבד בעצמו, עושה המרה "חשופה". הוא לא מוסיף כל עיצוב טקסט עשיר מיוחד, לא מוסיף צבעים וכו'.

אחד התחכות הנפוצות ביותר היא ניסיון להוסיף עיצוב נאה לפני ייצוא ל־CSV. רבים משתמשים ינסו לשפר את הפלט לפני שיצוא ל־CSV. אך אני עומד להראות לך שזה עשוי להקל על המצב במקום לשפר אותו.

אפשר לפתוח קובץ CSV ב-Microsoft Excel ולהוסיף עיצובים כמו כתב נטו, מודגש, צבעים ועוד, אבל אם תשמור את הקובץ כ-CSV (ולא כספריה של Excel), כל העיצוב יימחק. קובץ CSV פשוט לא מספיק "חכם".

שים לב שקבצי CSV הם פשוט קבצי טקסט רגילים עם ערכים מופרדים בפסיקים (או לעיתים טאבים). הפיכת Import-Csv לפקודת פייפ עם Format-* לא תעבוד כפי שציפית.

על פי תיעוד המסמך Export-Csv של Microsoft: "אל תעצבן את האובייקטים לפני שתשלח אותם לפקודת Export-CSV. אם Export-CSV מקבל אובייקטים מעוצבים, הקובץ CSV יכיל את תכונות העיצוב במקום תכונות האובייקט."

למה זה קורה?

פתח חלון PowerShell וצור נתוני דמיים. נשתמש בדוגמת Get-Process מהסעיף הראשון של המאמר הזה. אבל הפעם, הקצה את פלט הפקודה למשתנה. לאחר מכן, סנן את אובייקטי התהליכים האלה לפקודת Format-Table.

PS51> $a = Get-Process
PS51> $a | Format-Table
Using Format-Table

תוכל לראות שבעזרת Format-Table, יש לך פלט נקי וטבלאי.

עכשיו שמור את הפלט הזה למשתנה נוסף.

PS51> $b = $a | Format-Table

עכשיו הצג את התכונות בכל אחד מערכי הערכים $a ו-$b עם עזרת Get-Member. הפקודה הזו תעזור לך להבין למה שני האובייקטים האלו, שכמעט זהים במראהם, אינם מייצאים לקובץ CSV באותה דרך:

PS51> $a | Get-Member
System.Diagnostics.Process object type
PS51> $b | Get-Member
Format-Table‘s many object types

הפלט ישירות מ-Get-Process מחזיר: TypeName: System.Diagnostics.Process בעוד שהפלט מ-Format-Table שונה לחלוטין. הוא מחזיר מספר סוגים שונים עם מאפיינים שונים.

אם תצפה ב-$a וב-$b בקונסול, הפלט יראה זהה. התנהגות זו נגרמת על ידי מערכת העיצוב של PowerShell.

איך זה משפיע על הפלט של Export-Csv?

PS51> $b | Export-Csv | Format-Table

Export-Csv קוראת לכל אובייקט כפי שהוא. כאשר אתה משלב פלט ל-Format-* cmdlet, אתה משנה את הקלט ש-Export-CSV מקבל. זה משפיע על הפלט שמתווסף לקובץ CSV החדש שלך.

אם אתה מתכנן להפנות פלט ל-Export-Csv cmdlet, אל תפנה פלט לאף cmdlet של Format-*.

תזכור שקבצי CSV מתמקדים בנתונים, ולא בעיצוב.

הוספת נתונים לקובץ CSV

לפעמים ייתכן שתרצה להוסיף לקובץ קיים במקום ליצור חדש לחלוטין. כברירת מחדל, Export-Csv תמחק כל קובץ שצוין דרך הפרמטר Path.

אם נדרש להוסיף נתונים ל-CSV, השתמש בפרמטר Append.

תנא: נניח שיש לך לולאה שאתה רוצה לשמור על כל אובייקט שעובר דרך על קובץ CSV. לכל איטרציה, יש לך אובייקט שונה שברצונך לשמור בקובץ CSV. מכיוון שאתה קורא ל־Export-Csv מחדש פעמים רבות, זה ידרוס את קובץ ה־CSV אם אתה לא משתמש בפרמטר Append. בלעדיו, תקבל רק את האובייקט האחרון, שברוב המקרים אינו הפלט הרצוי.

הדוגמה למטה מוצאת את חמישת התהליכים הרצים הראשונים. לאחר מכן, היא נכנסת ללולאת foreach של PowerShell ומקליטה את המאפיינים Name ו־ProductVersion לקובץ test.csv אחד לכל פעם.

Get-Process | Select-Object -First 5 | Foreach-Object {
    $_ | Select-Object Name, ProductVersion | Export-CSV -Path C:\test.csv -Append
}

בלעדיו של פרמטר Append, תראה רק את התהליך החמישי בקובץ ה־CSV.

הוספת הבחנות לקובץ CSV

אפשר להוסיף רק את הבדלי המאפיינים לקובץ CSV קיים עם Export-Csv. זה אומר שאם עמודת ה־CSV של שורה והאובייקט לרשום שונים, אז תמשיך ותוסיף אותם.

כדי להוסיף רק את ההבדלים לקובץ CSV, יהיה עליך להשתמש בפרמטרים Append ו־Force יחד. על פי תיעוד של Microsoft "כאשר הפרמטרים Force ו־Append מתחברים, ייתכן לרשום אובייקטים שמכילים מאפיינים שונים לקובץ CSV. רק המאפיינים שתואמים ייכתבו לקובץ. המאפיינים שאינם תואמים יישלפו."

כדי להדגיש, צרו אובייקט אחד עם שתי מאפיינים; Name ו־Age.

PS51> $Content = [PSCustomObject]@{Name = "Johnny"; Age = "18"}

עכשיו צרו עוד אובייקט עם מאפיין Name ו־Zip.

PS51> $OtherContent = [PSCustomObject]@{Name = "Joe"; Zip = "02195"}

כל אובייקט כולל מאפיינים שונים.

לאחר מכן, צרו קובץ CSV מהאובייקט הראשון ונסו להוסיף את האובייקט השני ל־CSV ללא הפרמטר Force. תקבלו שגיאה.

PS51> $Content | Export-CSV -Path .\User.csv -NoTypeInformation
PS51> $OtherContent | Export-CSV -Path .\User.csv -NoTypeInformation -Append
Export-Csv without Force

אך, אם תשתמשו בפרמטר Force, Export-Csv יעבוד נהדר.

PS51> $OtherContent | Export-CSV -Path .\User.csv -NoTypeInformation -Append -Force

אף על פי כן, תשימו לב שעמודת Zip נעלמה מהקובץ CSV. עליכם להשתמש ב־Force בזהירות. זה עשוי לא לספק את הפלט הרצוי.

PS51> Import-Csv -Path .\User.csv

Name   Age
----   ---
Johnny 18
Joe

Export-CSV והמחרוזת #TYPE

במצב ברירת המחדל, השימוש ב־Export-CSV ללא פרמטרים נוספים יכלול מחרוזת #TYPE בראש קובץ ה־CSV שלכם. לאחר מכן מסומן סוג האובייקט שקיבל Export-Csv.

 #TYPE System.Diagnostics.Process 

רוב הזמן, המחרוזת הזו לא מועילה ממש כאשר מצרפים את הפלט. היא נמצאת שם רק במקרה שבו יש צורך לשמור על סוג האובייקט ממנו הבאו המאפיינים והערכים.

כדי להסיר את המחרוזת הזו, השתמשו בפרמטר NoTypeInformation. הפרמטר הזה מסיר את המחרוזת מה־CSV לחלוטין.

שימו לב שמאז PowerShell Core, זה כבר אינו נדרש.

תקציר

השימוש בפקודות ה-Import-CSV וה-Export-CSV בפוורשל מאפשר לך לעבוד בקלות עם קבצי CSV. אלה שני פקודות שימושיות שכדאי להשתמש בהן בתדירות כאשר אתה מתמודד עם אובייקטים וקבצי CSV.

מקוותי הוא שעם ההסברים והדוגמאות שהצגתי כאן, תוכל להבין באופן ברור את המקרים שבהם תוכל להשתמש בפקודות אלה לתועלתך.

רוצה עוד טיפים כמו זה? בדוק את ה-בלוג האישי שלי בפוורשל.

Source:
https://adamtheautomator.com/import-csv/