תווים כלליים לחיפוש של URI

כלי שורת הפקודה gcloud storage ו-gsutil תומכים בשימוש בתווים כלליים לחיפוש URI של קבצים, קטגוריות ואובייקטים. תווים כלליים לחיפוש מאפשרים לעבוד ביעילות עם קבוצות של קבצים שתואמות לתבניות ספציפיות של שמות. בדף הזה אנחנו מתארים את התווים הכלליים לחיפוש שכלי שורת הפקודה תומכים בהם, ומפרטים שיקולים שחשוב להתייחס אליהם כשמשתמשים בתווים כלליים לחיפוש בפקודות.

תווים כלליים לחיפוש

ב-gcloud storage וב-gsutil יש תמיכה בתווים הכלליים לחיפוש הבאים:

תו תיאור
* התאמה לאפס תווים או יותר ברמת הספרייה הנוכחית. לדוגמה, cp gs://my-bucket/abc/d* תואם לאובייקט abc/def.txt אבל לא לאובייקט abc/def/g.txt. במקרה של פקודות להצגת רשימה, כמו ls, אם * בסוף תואם לספריית משנה ברמת הספרייה הנוכחית, גם התוכן של ספריית המשנה יופיע.
** התאמה לאפס תווים או יותר מעבר לגבולות הספרייה. כשמשתמשים בתו הכללי לחיפוש ** בנתיב קובץ מקומי, תמיד צריך להופיע לפניו תו מפריד של ספרייה. לדוגמה, my-directory/**.txt הוא חוקי, אבל my-directory/abc** הוא לא חוקי.
? התאמה לתו יחיד. לדוגמה, gs://bucket/??.txt מבצע התאמה לאובייקטים שיש בהם בדיוק שני תווים עם המחרוזת .txt אחריהם.
[CHARACTERS] התאמה לפחות לאחד מהתווים שצוינו. לדוגמה, gs://bucket/[aeiou].txt תואם לאובייקטים שמכילים תו של תנועה אחת ואחריו .txt.
[CHARACTER_RANGE] התאמה לכל תו מטווח של התווים. לדוגמה, gs://bucket/[a-e].txt תואם לאובייקטים שמכילים את האות a‏, b‏, c‏, d או e ואחריה .txt.

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

gs://*/[a-m]??.j*g

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

ב-gcloud storage וב-gsutil יש תמיכה באותם תווים כלליים לחיפוש של שמות של אובייקטים ושל שמות של קבצים. כך, למשל:

cp data/abc* gs://bucket

תואם לכל הקבצים שמתחילים ב-abc בספרייה data של מערכת הקבצים המקומית.

שיקולי התנהגות

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

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

  • מעטפות (כמו bash ו-zsh) יכולות לנסות להרחיב תווים כלליים לחיפוש לפני העברת הארגומנטים אל gcloud storage או אל gsutil. אם התו הכללי לחיפוש אמור להתייחס לאובייקט בענן, יכולות להופיע שגיאות לא צפויות עם הודעת "לא נמצא". לדוגמה, המעטפת עשויה לנסות להרחיב את התו הכללי לחיפוש gs://my-bucket/* במחשב המקומי, ובגלל שלא תמצא התאמה לאף קובץ מקומי, הפקודה תיכשל.

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

    כדי למנוע את הבעיות האלה, צריך לתחום את התווים הכלליים לחיפוש במירכאות יחידות (ב-Linux) או במירכאות כפולות (ב-Windows).

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

    cp './file[1]' gs://my-bucket

    אף פעם לא מעתיקה קובץ מקומי בשם file[1]. במקום זאת, gcloud storage ו-gsutil תמיד מתייחסים ל-[1] כאל תו כללי לחיפוש.

    בשלב זה לא מתוכננת תמיכה במצב "גולמי", שמאפשר לכלי שורת הפקודה לעבוד עם שמות קבצים שמכילים תווים כלליים לחיפוש. לקבצים כאלה צריך להשתמש בכלי אחר, כמו מסוף Google Cloud, או להשתמש בתו כללי לחיפוש שימצא את הקבצים. לדוגמה, כדי למצוא קובץ בשם file[1], משתמשים בפקודה הבאה:

    cp './file*1*' gs://my-bucket
  • בהתאם להתנהגות הרגילה של Unix, התו הכללי לחיפוש * תואם רק לקבצים שלא מתחילים בתו . (כדי למנוע בלבול עם הספריות . ו-.. שנמצאות בכל ספריות ה-Unix). גם gcloud storage ו-gsutil פועלים באופן כזה כשמשתמשים בתווים כלליים לחיפוש URI של מערכת קבצים, אבל לא מתנהגים כך כשמדובר ב-URI בענן. לדוגמה, הפקודה הבאה מעתיקה את כל האובייקטים מ-gs://bucket1 ל-gs://bucket2:

    cp gs://bucket1/* gs://bucket2

    אבל הפקודה הבאה מעתיקה רק קבצים שלא מתחילים ב-. מהספרייה dir אל gs://bucket1:

    cp dir/* gs://bucket1

שיקולי יעילות

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

    gs://bucket/abc*.txt

    מאשר כשמשתמשים בתווים כלליים לחיפוש בתור החלק הראשון של שם האובייקט, כמו:

    gs://bucket/*abc.txt

    הסיבה לכך היא שהבקשה ל-gs://bucket/abc*.txt מבקשת מהשרת לשלוח בחזרה את קבוצת המשנה של התוצאות ששם האובייקט שלהן מתחיל ב-abc ברמה הבסיסית (root) של הקטגוריה, ואז מוצאת ברשימת התוצאות את האובייקטים ששמם מסתיים ב-.txt. לעומת זאת, הפקודה gs://bucket/*abc.txt מבקשת מהשרת את הרשימה המלאה של האובייקטים ברמה הבסיסית (root) של הקטגוריה, ואז מוצאת את האובייקטים ששמם מסתיים ב-abc.txt. השיקול הזה בנוגע ליעילות משמעותי אף יותר כשמשתמשים בקטגוריות המכילות אלפי אובייקטים או יותר. לפעמים אפשר להגדיר את השמות של האובייקטים כך שיתאימו לתבניות ההתאמה הצפויות של התווים הכלליים לחיפוש כדי לנצל את היעילות של בקשות לקידומת בצד השרת. דוגמה קונקרטית לכך אפשר לראות ב-gsutil Help Prod.

  • נניח שיש לכם קטגוריה עם האובייקטים הבאים:

    gs://bucket/obj1
    gs://bucket/obj2
    gs://bucket/obj3
    gs://bucket/obj4
    gs://bucket/dir1/obj5
    gs://bucket/dir2/obj6

    אם מריצים את הפקודה:

    gcloud storage ls gs://bucket/*/obj5

    gcloud storage יוצר רשימה מופרדת ב-/ של הרמה העליונה של הקטגוריה, ואז רשימה אחת לכל ספריית משנה בקטגוריה, כך שבסך הכול נוצרות 3 רשימות של הקטגוריה:

    GET /bucket/?delimiter=/
    GET /bucket/?prefix=dir1/obj5&delimiter=/
    GET /bucket/?prefix=dir2/obj5&delimiter=/
    

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

    • מספר הרכיבים של התו הכללי לחיפוש (למשל, ב-gs://bucket/a??b/c*/*/d יש 3 רכיבי תו כללי לחיפוש);

    • מספר ספריות המשנה שתואמות לכל רכיב, וגם

    • מספר התוצאות (כשמספר התוצאות גדול מדי הפירוט מתחלק לדפים, תוך ציון סמנים לכל תוצאה).

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

    gcloud storage ls gs://bucket/**/obj5

    הפעולה הזו מתאימה ליותר אובייקטים מ-gs://bucket/*/obj5 (כי היא כוללת כמה ספריות), אבל היא מוטמעת באמצעות בקשת רשימה בקטגוריה, ללא תו מפריד (כלומר, פחות בקשות לקטגוריה, למרות שהיא יוצרת רשימה של כל הקטגוריה ומסננת באופן מקומי, ולכן עשויה להשתמש בכמות די גדולה של תנועה ברשת).