קורס עבודה בסביבת Unix/Linux שיעור תרגול Shell Glob


זה נושא דיון מלווה לערך המקורי ב- https://www.tocode.co.il/bundles/unix1/lessons/globlab

שלום וברכה,

לשאלה 1. כל התיקיות ששמן מתחיל באות קטנה (תחת wildcards, לא באופן רקורסיבי, כך שיוצגו התיקיות src, include, lib ו img בלבד).

כתבתי:

*[ls -d [a-z

  1. כל התיקיות ששמן מתחיל באות גדולה

כתבתי:

*[ls -d [A-Z

אבל הוא לא מבדיל בין אותיות קטנות וגדולות (שיחקתי עם האותיות בסוגריים.

למה ומה עושים?

הי יהודה,

לפעמים האותיות ״מסודרות״ אחרת בראש של המחשב - כלומר במקום שיהיו מסודרות קודם כל האותיות הקטנות ואחר כך הגדולות הן מסודרות לפי האות עצמה כלומר aAbBcCdDeE וכך הלאה. בסידור כזה כשאתה מחפש את כל האותיות מ a עד z גם האותיות הגדולות ש״באמצע״ נכנסות לקבוצה ולכן יש הרגשה שאין הבדל בין אותיות גדולות וקטנות.

אני מציע להפעיל את הפקודה הבאה שקובעת את סידור האותיות בקידוד שנקרא ASCII בו האותיות מסודרות קודם הגדולות ואחר כך הקטנות:

export LC_ALL=POSIX

ונסה אחרי זה להריץ את פקודות החיפוש שלך

היי ינון,

  1. האם יש דרך קצרה יותר להגיע לתיקיה במקום להקליד את כל הנתיב מחדש כל פעם, למשל בהמשך לתרגיל כאשר אני יוצר כמה תיקיות באותה תיקיה בשביל להגיע לאחת מהן אני מקליד cd /home/username/folder כל הנתיב בשביל להגיע לתיקיה ולהיכנס על מנת לעשות פעולה, אודה לעזרתך.
  2. בהמשך לשאלה זו ולגבי סעיף 5 יש פקודה אחת למחיקת קבצים עם סיומת C אך אני צריך כל פעם מחדש לעשות אותה כאשר אני פונה לאותה תיקיה עם הקבצים אלה, ב man ב RM לא מצאתי או לפחות לא הבנתי לגבי אפשרות כזו,שוב אודה לעזרתך.

הי @ehudpi

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

אפשר לעבור לתיקיה גם לפי נתיב יחסי - כלומר אם אני בנתיב /home/ynon מספיק לי לכתוב:

cd foo

כדי להגיע ל:

/home/ynon/foo

לגבי 2 - למה אתה מתכוון?

היי ינון,

תודה על התשובה הראשונה!

לגבי 2 כנראה לא הבנתי את התרגיל, יש אפשרות לקבל הנסבר נוסף?

על איזה סעיף בדיוק מדובר?

שלום
תודה רבה על הקורס המושקע
אשמח להסבר בסעיף 6 לא הצלחתי להסתדר
תודה

לייק 1

הי @ym1

אתה מתכוון לתת-סעיף 6 בתוך 4, או לסעיף 6 הראשי? ומה ניסית לעשות?

שלום
שאלה 4 סעיף 6-
מקבל “ls cannot access *.c:No such file or directory”
בהפעלת מהתיקייה wildcards:
ls *.c
ls -R *.c
ls -l *.c
ls -alR *.c
אבל הפעלה של ls *.c בתוך תיקייה lib למשל עובדת.
מה הסיבה? ומה חסר בשביל הפתרון?

שלום,
גם אצלי בשאלה 6, קריאה לפקודה
ls -l [A-Z]*
מחזירה:
README.txt -תקין מתחיל באות גדולה
test.c - לא תקין , מתחיל באות קטנה

קריאה ל export LC_ALL=POSIX לא פתר לי את זה

הי,

נתחיל עם השאלה השניה שלך כי יותר קל לענות עליה. הבעיה הפעם לא קשורה לסדר האותיות אלא למה שמוצג. במבנה הפרויקט בדוגמה הקובץ test.c הוא בכלל לא נמצא בתיקיה בה אתה מריץ את הפקודה - אלא בתיקיה אחת פנימית יותר. מבנה התיקיות הוא קודם כל תיקיית Doc ורק בתוכה הקובץ test.c

עכשיו עוד כמה פקודות שיעזרו להבין מה קורה פה. נסה להפעיל:

ls Doc

ואתה תראה תופעה מעניינת - במקום לראות את השם Doc אתה רואה את רשימת הקבצים שיש בתוך תיקיית Doc.

עכשיו אם נחזור ל ls שאתה הפעלת, אז מבחינת המחשב כתוב:

ls [A-Z]*

הוא מסתכל בתיקיה ומחפש את הקבצים והתיקיות שמתחילים באות גדולה. מצא את Doc ולכן מחליף את ה Glob Pattern שכתבת במילה Doc ומריץ:

ls Doc

והתוצאה של זה היא בדיוק מה שאתה קיבלת כשהרצת לבד את ls Doc, כלומר רשימת כל הקבצים בתיקיית Doc.

הרבה פעמים כשמשתמשים ב Glob Patterns עם תיקיות ועם ls אנחנו מוסיפים ל ls את האפשרות -d. אפשרות זו גורמת ל ls לא להדפיס את רשימת הקבצים בתוך תיקיה אלא את שם התיקיה עצמה. נסה את אלה אצלך ותראה מה קורה:

ls Doc
ls -d Doc
ls [A-Z]*
ls -d [A-Z]*

שאלה 4 סעיף 6.
שימוש ב:

1. ls */*.c

או

2. ls *//*.c

מחזיר את כל קבצי ה- C .
אך יש איתם בעיה.

אם יוצרים למשל touch a.c בתיקיה wildecard ,
אז (1) הוא יורד רמה אחת בעץ התיקיות ומחפש שם - לכן הוא לא ימצא a.c וגם לא ימצא קובץ ברמה יותר נמוכה.

קריאה ל -(2) ls //.c מחזיר רק a.c כל עוד הוא קיים,
ואם מחוקים אותו אז מחזיר
Doc/test.c
lib/zlib.c
src/main.c
src/player.c
וגם הוא יורד לכל היותר רמה אחת.
זא אם יש לי קובץ ב-
wildcards/include/shared/b.c
אז אותו הוא יפספס בדיוק כמו (1)

מבקש עזרה עם התרגיל.
חיפוש בגוגל לא הועיל מכיוון ששם או מסבירים בכללי על LS או משתמשים ב- FIND ו-GREP

הי

זה נכון מאוד מה שכתבת. באמת אנחנו יכולים להשתמש ב Glob Patterns רק אם אנחנו יודעים מה המבנה של הדבר שאנחנו מחפשים - ובגלל זה אפשר לכתוב:

*.c

או

*/*.c

בגירסאות עדכניות של bash יש אופציה שנקראת globstar שקצת פותרת את הבעיה הזאת. אפשר לקרוא עליה כאן:
https://www.linuxjournal.com/content/globstar-new-bash-globbing-option

אבל בגדול הרבה פעמים נשתמש בכלי כמו find כדי למצוא את כל הקבצים כשאנחנו לא בטוחים מה המבנה. בקורס יש שיעור על find שבאמת פותר את האתגר הזה בצורה יותר גנרית:
https://www.tocode.co.il/bundles/unix1/lessons/find

היי לא מצליח להציג את כל הקבצים שמסתיימים נגיד ב.c כאשר אני לא נמצא בתיקייה עצמה

ויש שאלה של למחוק את כל קבצי .png מכל התיקיות עשיתי איזה פקודה אבל זה מחק גם את התייקיה עצמה

הי אמיר

יכול להדביק פה איזה פקודות ניסית להפעיל?

תרגול SHELL GLOB

בעיה בשאלה 6
הפקודה ls -l מקבלת שם של קובץ או תיקיה ומציגה פרטים לגביהם. נסו להריץ את הפקודה ls -l /etc/passwd ולראות את הפרטים ולאחר מכן הריצו מתוך תיקיית wildcards את הפקודה ls -l [A-Z]*. מה הודפס? מדוע?

תשובות שעשיתי לשאר השאלות

1. mkdir wildcards
2.mkdir Doc img lib include src
3.touch src/main.c include/player.h src/player.c img/hero.png lib/zlib.c Doc/README.txt img/player.png Doc/test.c

4.1
echo [a-z]*

4.2
echo [A-Z]*

4.3
echo *[a,e,u,i,o]

4.4
echo *[!a,e,u,i,o]

4.5
find src/ -maxdepth 1 -name *.c -type f

4.6
find -name *.c -type f

5.
find -name.png -type f -print -delete

6.
הודפס לי אבל לא הבנתי מה אני אמור לראות ולמה

7.
ls -d D*
לייק 1

לגבי 6 - מה הודפס? איזה קבצים יש בתיקיה? האם הודפס מה שהתכוונת שיודפס?

Hi Ynon,
I git cloned labs from

/unix1-course-examples/12_glob_lab$ tree
.
├── Doc
│ ├── README.txt
│ └── test.c
├── globlab.txt
├── img
│ ├── hero.png
│ └── player.png
├── include
│ └── player.h
├── lib
│ └── zlib.c
└── src
├── main.c
└── player.c

export LC_ALL=POSIX

Question
3. All files whose name ends in an “a”, “e”, “i”, “o” or “u”

Answer:

  /unix1-course-examples/12_glob_lab$ ls  *[aeiou]
  player.h

I can’t understand why that player.h appears, it shouldn’t…

תודה

Hi,
Sorry for the delay I must have missed the notifications

Anyway it is confusing by design :slight_smile:
try to replace ls with echo, and you’ll see that the output you get is just the directory include which matches the criterion,
Now run ls include and you’ll see that the output is the file name player.h

Basically when ls takes just one argument and that argument is a directory, it will print all the files inside that directory

לייק 1