• בלוג
  • דוגמת awk: יצירת קבצים ותיקיות על פי קובץ טקסט

דוגמת awk: יצירת קבצים ותיקיות על פי קובץ טקסט

פוסט זה כולל טיפ קצר על כלי עבודה בסביבת Linux. בשביל ללמוד יותר על עבודה בסביבת Linux ו Unix אני ממליץ לכם לבדוק את קורס Linux שיש לנו כאן באתר. הקורס כולל מעל 50 שיעורי וידאו והמון תרגול מעשי ומתאים גם למתחילים.
 

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

בקורס השבוע דיברנו על יצירה אוטומטית של קבצי סטארטר לתרגול. כך זה נראה ב awk.

1. תיאור הבעיה

נתון קובץ תרגילים בפורמט markdown המחולק לפרקים, למשל עם התוכן הבא:

## Part 1
1. Write a shell script that takes a file name as a command line argument and prints its contents backwards (from last line to first). Hint: Use tac
5. Print a list of all the  file extensions in current folder using only shell builtins (no `cut`, `awk`, `sed`, `grep` or `tr`)
6. Print a list of all the file extensions in the current folder, showing each extension only once

## Part 2
2. Write a shell script that takes 3 input arguments and prints out the largest one
3. Write a shell script that reads a name from the user - if that name is an executable program run it, otherwise print its content.
  If it's not a file print an error message.
7. Write a shell script that reads a file name from the user, checks that the file is valid, and lowecases its name. For example, running `lc MyFile` should rename the file `MyFile` to `myfile`.
8. Write a shell script that prints the sum of its arguments

## Part 3
6. Write a shell script that takes a two file extensions as input (call them ext1 and ext2), and renames all files ending with ext1 to end with ext2.
7. write a shell script that takes several file names as inputs, and copies itself to each of the files. don't forget to set execute permissions on the target files.

נרצה לייצר לכל חלק בדף התרגילים תיקיה התחלתית, ובתוכה קובץ סטארטר לכל סעיף שיכלול כותרת של קובץ csh ואת המשימה עצמה כהערה.

2. פתרון פשוט ב awk

קל לראות שהקובץ מחולק לבלוקים ובתוכם לסעיפים. כל בלוק מתחיל בשתי סולמיות ולאחריהן מספר הבלוק. השורות הבאות כוללות את המשימות ועלינו ליצור קובץ עבור כל אחת מהן.

ל awk יש תמיכה במשתנים ולכן הפתרון יורכב מ-3 פקודות:

  1. בכל פעם שנזהה בלוק חדש נרצה לעדכן משתנה שמחזיק את שם הבלוק הנוכחי.
  2. בכל פעם שנזהה משימה חדשה (שורה שמתחילה במספר ואז נקודה) נרצה לעדכן משתנה שמחזיק את מספר המשימה הנוכחית, וגם ליצור קובץ משימה התחלתי.
  3. עבור כל שורה שאינה פותחת בלוק נרצה לכתוב את תוכנה לקובץ המשימה הנוכחי.

הקוד המלא ב awk נראה כך:

#!/usr/local/bin/awk -f

/^## Part [0-9]+/ {
  task = 1
  part = $3
  system("mkdir " part)
  next
}

/^[0-9]+\./ {
  fname = sprintf("%s/%.2d.csh", part, task)
  print "#!/bin/tcsh -fe" > fname
  print "set noclobber nonomatch" > fname
  system("chmod +x " fname)
  sub(/^[0-9]+\.\s*/, "")
  task++
}

// {
  print "# " $0 > fname
}

רוצים לנסות להריץ? קבלו קונסול עם התוכנית וקובץ הקלט. מה שיותר נחמד, שאפשר להשתמש ב fold כדי לשבור שורות ארוכות ולכן השורה שאני מריץ היא:

fold -s -w 60 lab.md | ./split.awk 

נסו בעצמכם!