[{"data":1,"prerenderedAt":2906},["ShallowReactive",2],{"guides-index":3},[4],{"id":5,"title":6,"body":7,"cta":2870,"date":2875,"description":2876,"draft":2877,"extension":2878,"meta":2879,"navigation":130,"ogImage":2880,"path":2885,"readingTime":2886,"robots":2887,"schemaOrg":2888,"seo":2895,"sitemap":2896,"stem":2899,"tags":2900,"__hash__":2905},"guides_en\u002Fguides\u002Fzsh-scripting-cheatsheet.md","Zsh Scripting Cheatsheet for Advanced Automation",{"type":8,"value":9,"toc":2848},"minimark",[10,14,18,23,56,78,82,87,205,209,403,407,513,517,768,772,975,979,1154,1158,1301,1305,1539,1543,1823,1827,1922,1926,2085,2089,2272,2276,2332,2336,2339,2734,2738,2811,2815,2844],[11,12,6],"h1",{"id":13},"zsh-scripting-cheatsheet-for-advanced-automation",[15,16,17],"p",{},"Zsh isn't just a better-looking bash. Once you understand its advanced features, you can write scripts that are shorter, safer, and more expressive. This guide covers the patterns I use daily for automation, devops tooling, and CLI utilities.",[19,20,22],"h2",{"id":21},"start-every-script-right","Start Every Script Right",[24,25,30],"pre",{"className":26,"code":27,"language":28,"meta":29,"style":29},"language-zsh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","#!\u002Fusr\u002Fbin\u002Fenv zsh\nset -euo pipefail\n","zsh","",[31,32,33,42],"code",{"__ignoreMap":29},[34,35,38],"span",{"class":36,"line":37},"line",1,[34,39,41],{"class":40},"sHwdD","#!\u002Fusr\u002Fbin\u002Fenv zsh\n",[34,43,45,49,53],{"class":36,"line":44},2,[34,46,48],{"class":47},"s2Zo4","set",[34,50,52],{"class":51},"sfazB"," -euo",[34,54,55],{"class":51}," pipefail\n",[57,58,59,66,72],"ul",{},[60,61,62,65],"li",{},[31,63,64],{},"set -e",": Exit immediately if a command fails",[60,67,68,71],{},[31,69,70],{},"set -u",": Treat unset variables as errors",[60,73,74,77],{},[31,75,76],{},"set -o pipefail",": Pipeline fails if any command fails, not just the last",[19,79,81],{"id":80},"parameter-expansion-the-real-power","Parameter Expansion: The Real Power",[83,84,86],"h3",{"id":85},"default-values","Default Values",[24,88,90],{"className":26,"code":89,"language":28,"meta":29,"style":29},"# Use default if unset or empty\nname=${1:-\"world\"}\n\n# Use default only if unset (empty string is valid)\nname=${1-\"world\"}\n\n# Set default if unset\n: ${CONFIG_FILE:=~\u002F.config\u002Fmyapp\u002Fconfig.yaml}\n",[31,91,92,97,125,132,138,158,163,169],{"__ignoreMap":29},[34,93,94],{"class":36,"line":37},[34,95,96],{"class":40},"# Use default if unset or empty\n",[34,98,99,103,107,111,114,117,120,122],{"class":36,"line":44},[34,100,102],{"class":101},"sTEyZ","name",[34,104,106],{"class":105},"sMK4o","=",[34,108,110],{"class":109},"sHdIc","${1",[34,112,113],{"class":105},":-",[34,115,116],{"class":105},"\"",[34,118,119],{"class":51},"world",[34,121,116],{"class":105},[34,123,124],{"class":109},"}\n",[34,126,128],{"class":36,"line":127},3,[34,129,131],{"emptyLinePlaceholder":130},true,"\n",[34,133,135],{"class":36,"line":134},4,[34,136,137],{"class":40},"# Use default only if unset (empty string is valid)\n",[34,139,141,143,145,147,150,152,154,156],{"class":36,"line":140},5,[34,142,102],{"class":101},[34,144,106],{"class":105},[34,146,110],{"class":109},[34,148,149],{"class":101},"-",[34,151,116],{"class":105},[34,153,119],{"class":51},[34,155,116],{"class":105},[34,157,124],{"class":109},[34,159,161],{"class":36,"line":160},6,[34,162,131],{"emptyLinePlaceholder":130},[34,164,166],{"class":36,"line":165},7,[34,167,168],{"class":40},"# Set default if unset\n",[34,170,172,175,178,181,184,187,190,193,195,198,200,203],{"class":36,"line":171},8,[34,173,174],{"class":47},":",[34,176,177],{"class":105}," ${",[34,179,180],{"class":101},"CONFIG_FILE",[34,182,183],{"class":105},":=",[34,185,186],{"class":101},"~",[34,188,189],{"class":105},"\u002F",[34,191,192],{"class":101},".config",[34,194,189],{"class":105},[34,196,197],{"class":101},"myapp",[34,199,189],{"class":105},[34,201,202],{"class":101},"config.yaml",[34,204,124],{"class":105},[83,206,208],{"id":207},"string-manipulation","String Manipulation",[24,210,212],{"className":26,"code":211,"language":28,"meta":29,"style":29},"path=\"\u002Fhome\u002Fuser\u002Fdocuments\u002Ffile.txt\"\n\n# Remove shortest match from end\n${path%.*}        # \u002Fhome\u002Fuser\u002Fdocuments\u002Ffile\n\n# Remove longest match from end\n${path%%\u002F*}       # (empty - removes everything)\n${path##*\u002F}       # file.txt\n\n# Remove shortest match from beginning\n${path#*\u002F}        # home\u002Fuser\u002Fdocuments\u002Ffile.txt\n\n# Remove longest match from beginning\n${path##*\u002F}       # file.txt\n\n# Replace first occurrence\n${path\u002Fuser\u002Fadmin}    # \u002Fhome\u002Fadmin\u002Fdocuments\u002Ffile.txt\n\n# Replace all occurrences\n${path\u002F\u002F\\\u002F\u002F-}         # -home-user-documents-file.txt\n",[31,213,214,229,233,238,257,261,266,278,290,295,301,314,319,325,336,341,347,370,375,381],{"__ignoreMap":29},[34,215,216,219,221,223,226],{"class":36,"line":37},[34,217,218],{"class":101},"path",[34,220,106],{"class":105},[34,222,116],{"class":105},[34,224,225],{"class":51},"\u002Fhome\u002Fuser\u002Fdocuments\u002Ffile.txt",[34,227,228],{"class":105},"\"\n",[34,230,231],{"class":36,"line":44},[34,232,131],{"emptyLinePlaceholder":130},[34,234,235],{"class":36,"line":127},[34,236,237],{"class":40},"# Remove shortest match from end\n",[34,239,240,243,245,248,251,254],{"class":36,"line":134},[34,241,242],{"class":105},"${",[34,244,218],{"class":101},[34,246,247],{"class":105},"%",[34,249,250],{"class":101},".",[34,252,253],{"class":105},"*}",[34,255,256],{"class":40},"        # \u002Fhome\u002Fuser\u002Fdocuments\u002Ffile\n",[34,258,259],{"class":36,"line":140},[34,260,131],{"emptyLinePlaceholder":130},[34,262,263],{"class":36,"line":160},[34,264,265],{"class":40},"# Remove longest match from end\n",[34,267,268,270,272,275],{"class":36,"line":165},[34,269,242],{"class":105},[34,271,218],{"class":101},[34,273,274],{"class":105},"%%\u002F*}",[34,276,277],{"class":40},"       # (empty - removes everything)\n",[34,279,280,282,284,287],{"class":36,"line":171},[34,281,242],{"class":105},[34,283,218],{"class":101},[34,285,286],{"class":105},"##*\u002F}",[34,288,289],{"class":40},"       # file.txt\n",[34,291,293],{"class":36,"line":292},9,[34,294,131],{"emptyLinePlaceholder":130},[34,296,298],{"class":36,"line":297},10,[34,299,300],{"class":40},"# Remove shortest match from beginning\n",[34,302,304,306,308,311],{"class":36,"line":303},11,[34,305,242],{"class":105},[34,307,218],{"class":101},[34,309,310],{"class":105},"#*\u002F}",[34,312,313],{"class":40},"        # home\u002Fuser\u002Fdocuments\u002Ffile.txt\n",[34,315,317],{"class":36,"line":316},12,[34,318,131],{"emptyLinePlaceholder":130},[34,320,322],{"class":36,"line":321},13,[34,323,324],{"class":40},"# Remove longest match from beginning\n",[34,326,328,330,332,334],{"class":36,"line":327},14,[34,329,242],{"class":105},[34,331,218],{"class":101},[34,333,286],{"class":105},[34,335,289],{"class":40},[34,337,339],{"class":36,"line":338},15,[34,340,131],{"emptyLinePlaceholder":130},[34,342,344],{"class":36,"line":343},16,[34,345,346],{"class":40},"# Replace first occurrence\n",[34,348,350,352,354,356,359,361,364,367],{"class":36,"line":349},17,[34,351,242],{"class":105},[34,353,218],{"class":101},[34,355,189],{"class":105},[34,357,358],{"class":101},"user",[34,360,189],{"class":105},[34,362,363],{"class":101},"admin",[34,365,366],{"class":105},"}",[34,368,369],{"class":40},"    # \u002Fhome\u002Fadmin\u002Fdocuments\u002Ffile.txt\n",[34,371,373],{"class":36,"line":372},18,[34,374,131],{"emptyLinePlaceholder":130},[34,376,378],{"class":36,"line":377},19,[34,379,380],{"class":40},"# Replace all occurrences\n",[34,382,384,386,388,391,394,396,398,400],{"class":36,"line":383},20,[34,385,242],{"class":105},[34,387,218],{"class":101},[34,389,390],{"class":105},"\u002F\u002F",[34,392,393],{"class":101},"\\\u002F",[34,395,189],{"class":105},[34,397,149],{"class":101},[34,399,366],{"class":105},[34,401,402],{"class":40},"         # -home-user-documents-file.txt\n",[83,404,406],{"id":405},"variable-inspection","Variable Inspection",[24,408,410],{"className":26,"code":409,"language":28,"meta":29,"style":29},"var=\"hello world\"\n\n${#var}           # 11 (length)\n${var:0:5}        # hello (substring)\n${var:6}          # world (from index 6 to end)\n${var[-1]}        # d (last character, zsh-only)\n${var[1,5]}       # hello (zsh-style slice)\n",[31,411,412,426,430,442,463,479,497],{"__ignoreMap":29},[34,413,414,417,419,421,424],{"class":36,"line":37},[34,415,416],{"class":101},"var",[34,418,106],{"class":105},[34,420,116],{"class":105},[34,422,423],{"class":51},"hello world",[34,425,228],{"class":105},[34,427,428],{"class":36,"line":44},[34,429,131],{"emptyLinePlaceholder":130},[34,431,432,435,437,439],{"class":36,"line":127},[34,433,434],{"class":105},"${#",[34,436,416],{"class":101},[34,438,366],{"class":105},[34,440,441],{"class":40},"           # 11 (length)\n",[34,443,444,446,448,450,453,455,458,460],{"class":36,"line":134},[34,445,242],{"class":105},[34,447,416],{"class":101},[34,449,174],{"class":105},[34,451,452],{"class":101},"0",[34,454,174],{"class":105},[34,456,457],{"class":101},"5",[34,459,366],{"class":105},[34,461,462],{"class":40},"        # hello (substring)\n",[34,464,465,467,469,471,474,476],{"class":36,"line":140},[34,466,242],{"class":105},[34,468,416],{"class":101},[34,470,174],{"class":105},[34,472,473],{"class":101},"6",[34,475,366],{"class":105},[34,477,478],{"class":40},"          # world (from index 6 to end)\n",[34,480,481,483,485,488,491,494],{"class":36,"line":160},[34,482,242],{"class":105},[34,484,416],{"class":101},[34,486,487],{"class":105},"[",[34,489,490],{"class":101},"-1",[34,492,493],{"class":105},"]}",[34,495,496],{"class":40},"        # d (last character, zsh-only)\n",[34,498,499,501,503,505,508,510],{"class":36,"line":165},[34,500,242],{"class":105},[34,502,416],{"class":101},[34,504,487],{"class":105},[34,506,507],{"class":101},"1,5",[34,509,493],{"class":105},[34,511,512],{"class":40},"       # hello (zsh-style slice)\n",[19,514,516],{"id":515},"arrays-zsh-does-them-right","Arrays: Zsh Does Them Right",[24,518,520],{"className":26,"code":519,"language":28,"meta":29,"style":29},"# Define arrays\nfiles=(*.txt)\nhosts=(web1 web2 db1 db2)\n\n# Append\nhosts+=(cache1)\n\n# Access elements\n${hosts[1]}       # web1 (zsh is 1-indexed!)\n${hosts[-1]}      # cache1 (last element)\n${hosts[2,4]}     # web2 db1 db2 (slice)\n\n# All elements\n${hosts[@]}       # web1 web2 db1 db2 cache1\n${#hosts[@]}      # 5 (count)\n\n# Iterate\nfor host in $hosts; do\n  ssh $host \"uptime\"\ndone\n\n# Join with delimiter\nlocal IFS=,\nhosts_string=\"${hosts[*]}\"   # web1,web2,db1,db2,cache1\n",[31,521,522,527,541,563,567,572,584,588,593,609,624,640,644,649,661,672,676,681,702,718,723,728,734,749],{"__ignoreMap":29},[34,523,524],{"class":36,"line":37},[34,525,526],{"class":40},"# Define arrays\n",[34,528,529,532,535,538],{"class":36,"line":44},[34,530,531],{"class":101},"files",[34,533,534],{"class":105},"=(*",[34,536,537],{"class":51},".txt",[34,539,540],{"class":105},")\n",[34,542,543,546,549,552,555,558,561],{"class":36,"line":127},[34,544,545],{"class":101},"hosts",[34,547,548],{"class":105},"=(",[34,550,551],{"class":51},"web1",[34,553,554],{"class":51}," web2",[34,556,557],{"class":51}," db1",[34,559,560],{"class":51}," db2",[34,562,540],{"class":105},[34,564,565],{"class":36,"line":134},[34,566,131],{"emptyLinePlaceholder":130},[34,568,569],{"class":36,"line":140},[34,570,571],{"class":40},"# Append\n",[34,573,574,576,579,582],{"class":36,"line":160},[34,575,545],{"class":101},[34,577,578],{"class":105},"+=(",[34,580,581],{"class":51},"cache1",[34,583,540],{"class":105},[34,585,586],{"class":36,"line":165},[34,587,131],{"emptyLinePlaceholder":130},[34,589,590],{"class":36,"line":171},[34,591,592],{"class":40},"# Access elements\n",[34,594,595,597,599,601,604,606],{"class":36,"line":292},[34,596,242],{"class":105},[34,598,545],{"class":101},[34,600,487],{"class":105},[34,602,603],{"class":101},"1",[34,605,493],{"class":105},[34,607,608],{"class":40},"       # web1 (zsh is 1-indexed!)\n",[34,610,611,613,615,617,619,621],{"class":36,"line":297},[34,612,242],{"class":105},[34,614,545],{"class":101},[34,616,487],{"class":105},[34,618,490],{"class":101},[34,620,493],{"class":105},[34,622,623],{"class":40},"      # cache1 (last element)\n",[34,625,626,628,630,632,635,637],{"class":36,"line":303},[34,627,242],{"class":105},[34,629,545],{"class":101},[34,631,487],{"class":105},[34,633,634],{"class":101},"2,4",[34,636,493],{"class":105},[34,638,639],{"class":40},"     # web2 db1 db2 (slice)\n",[34,641,642],{"class":36,"line":316},[34,643,131],{"emptyLinePlaceholder":130},[34,645,646],{"class":36,"line":321},[34,647,648],{"class":40},"# All elements\n",[34,650,651,653,655,658],{"class":36,"line":327},[34,652,242],{"class":105},[34,654,545],{"class":101},[34,656,657],{"class":105},"[@]}",[34,659,660],{"class":40},"       # web1 web2 db1 db2 cache1\n",[34,662,663,665,667,669],{"class":36,"line":338},[34,664,434],{"class":105},[34,666,545],{"class":101},[34,668,657],{"class":105},[34,670,671],{"class":40},"      # 5 (count)\n",[34,673,674],{"class":36,"line":343},[34,675,131],{"emptyLinePlaceholder":130},[34,677,678],{"class":36,"line":349},[34,679,680],{"class":40},"# Iterate\n",[34,682,683,687,690,693,696,699],{"class":36,"line":372},[34,684,686],{"class":685},"s7zQu","for",[34,688,689],{"class":101}," host ",[34,691,692],{"class":685},"in",[34,694,695],{"class":101}," $hosts",[34,697,698],{"class":105},";",[34,700,701],{"class":685}," do\n",[34,703,704,708,711,713,716],{"class":36,"line":377},[34,705,707],{"class":706},"sBMFI","  ssh",[34,709,710],{"class":101}," $host ",[34,712,116],{"class":105},[34,714,715],{"class":51},"uptime",[34,717,228],{"class":105},[34,719,720],{"class":36,"line":383},[34,721,722],{"class":685},"done\n",[34,724,726],{"class":36,"line":725},21,[34,727,131],{"emptyLinePlaceholder":130},[34,729,731],{"class":36,"line":730},22,[34,732,733],{"class":40},"# Join with delimiter\n",[34,735,737,741,744,746],{"class":36,"line":736},23,[34,738,740],{"class":739},"spNyl","local",[34,742,743],{"class":101}," IFS",[34,745,106],{"class":105},[34,747,748],{"class":101},",\n",[34,750,752,755,757,760,762,765],{"class":36,"line":751},24,[34,753,754],{"class":101},"hosts_string",[34,756,106],{"class":105},[34,758,759],{"class":105},"\"${",[34,761,545],{"class":101},[34,763,764],{"class":105},"[*]}\"",[34,766,767],{"class":40},"   # web1,web2,db1,db2,cache1\n",[19,769,771],{"id":770},"globbing-pattern-matching-on-steroids","Globbing: Pattern Matching on Steroids",[24,773,775],{"className":26,"code":774,"language":28,"meta":29,"style":29},"# Recursive glob (no need for find)\nls **\u002F*.py\n\n# Case-insensitive glob\nls (#i)*.txt       # matches FILE.TXT, File.txt, etc.\n\n# Glob qualifiers (most powerful feature)\nls -l *(.)         # regular files only\nls -l *(@)         # symbolic links\nls -l *(\u002F)         # directories only\nls -l *(*W)        # world-writable files\n\n# Sort by modification time, get 5 most recent\nls -lt *(om[1,5])\n\n# Files larger than 1MB\nls -lh *(.LM+1)\n\n# Empty directories\nrmdir **\u002F*(\u002FDod)\n",[31,776,777,782,798,802,807,814,818,823,844,862,879,898,902,907,923,927,932,948,952,957],{"__ignoreMap":29},[34,778,779],{"class":36,"line":37},[34,780,781],{"class":40},"# Recursive glob (no need for find)\n",[34,783,784,787,790,792,795],{"class":36,"line":44},[34,785,786],{"class":706},"ls",[34,788,789],{"class":101}," **",[34,791,189],{"class":51},[34,793,794],{"class":101},"*",[34,796,797],{"class":51},".py\n",[34,799,800],{"class":36,"line":127},[34,801,131],{"emptyLinePlaceholder":130},[34,803,804],{"class":36,"line":134},[34,805,806],{"class":40},"# Case-insensitive glob\n",[34,808,809,811],{"class":36,"line":140},[34,810,786],{"class":706},[34,812,813],{"class":101}," (#i)*.txt       # matches FILE.TXT, File.txt, etc.\n",[34,815,816],{"class":36,"line":160},[34,817,131],{"emptyLinePlaceholder":130},[34,819,820],{"class":36,"line":165},[34,821,822],{"class":40},"# Glob qualifiers (most powerful feature)\n",[34,824,825,827,830,833,836,838,841],{"class":36,"line":171},[34,826,786],{"class":706},[34,828,829],{"class":51}," -l",[34,831,832],{"class":101}," *",[34,834,835],{"class":105},"(",[34,837,250],{"class":47},[34,839,840],{"class":105},")",[34,842,843],{"class":40},"         # regular files only\n",[34,845,846,848,850,852,854,857,859],{"class":36,"line":292},[34,847,786],{"class":706},[34,849,829],{"class":51},[34,851,832],{"class":101},[34,853,835],{"class":105},[34,855,856],{"class":706},"@",[34,858,840],{"class":105},[34,860,861],{"class":40},"         # symbolic links\n",[34,863,864,866,868,870,872,874,876],{"class":36,"line":297},[34,865,786],{"class":706},[34,867,829],{"class":51},[34,869,832],{"class":101},[34,871,835],{"class":105},[34,873,189],{"class":706},[34,875,840],{"class":105},[34,877,878],{"class":40},"         # directories only\n",[34,880,881,883,885,887,890,893,895],{"class":36,"line":303},[34,882,786],{"class":706},[34,884,829],{"class":51},[34,886,832],{"class":101},[34,888,889],{"class":105},"(*",[34,891,892],{"class":101},"W",[34,894,840],{"class":105},[34,896,897],{"class":40},"        # world-writable files\n",[34,899,900],{"class":36,"line":316},[34,901,131],{"emptyLinePlaceholder":130},[34,903,904],{"class":36,"line":321},[34,905,906],{"class":40},"# Sort by modification time, get 5 most recent\n",[34,908,909,911,914,916,918,921],{"class":36,"line":327},[34,910,786],{"class":706},[34,912,913],{"class":51}," -lt",[34,915,832],{"class":101},[34,917,835],{"class":105},[34,919,920],{"class":706},"om[1,5]",[34,922,540],{"class":105},[34,924,925],{"class":36,"line":338},[34,926,131],{"emptyLinePlaceholder":130},[34,928,929],{"class":36,"line":343},[34,930,931],{"class":40},"# Files larger than 1MB\n",[34,933,934,936,939,941,943,946],{"class":36,"line":349},[34,935,786],{"class":706},[34,937,938],{"class":51}," -lh",[34,940,832],{"class":101},[34,942,835],{"class":105},[34,944,945],{"class":706},".LM+1",[34,947,540],{"class":105},[34,949,950],{"class":36,"line":372},[34,951,131],{"emptyLinePlaceholder":130},[34,953,954],{"class":36,"line":377},[34,955,956],{"class":40},"# Empty directories\n",[34,958,959,962,964,966,968,970,973],{"class":36,"line":383},[34,960,961],{"class":706},"rmdir",[34,963,789],{"class":101},[34,965,189],{"class":51},[34,967,794],{"class":101},[34,969,835],{"class":105},[34,971,972],{"class":706},"\u002FDod",[34,974,540],{"class":105},[83,976,978],{"id":977},"glob-qualifiers-reference","Glob Qualifiers Reference",[980,981,982,995],"table",{},[983,984,985],"thead",{},[986,987,988,992],"tr",{},[989,990,991],"th",{},"Qualifier",[989,993,994],{},"Meaning",[996,997,998,1008,1017,1026,1035,1045,1055,1065,1075,1084,1094,1104,1114,1124,1134,1144],"tbody",{},[986,999,1000,1005],{},[1001,1002,1003],"td",{},[31,1004,250],{},[1001,1006,1007],{},"Regular files",[986,1009,1010,1014],{},[1001,1011,1012],{},[31,1013,189],{},[1001,1015,1016],{},"Directories",[986,1018,1019,1023],{},[1001,1020,1021],{},[31,1022,856],{},[1001,1024,1025],{},"Symbolic links",[986,1027,1028,1032],{},[1001,1029,1030],{},[31,1031,794],{},[1001,1033,1034],{},"Executable files",[986,1036,1037,1042],{},[1001,1038,1039],{},[31,1040,1041],{},"r",[1001,1043,1044],{},"Readable by owner",[986,1046,1047,1052],{},[1001,1048,1049],{},[31,1050,1051],{},"w",[1001,1053,1054],{},"Writable by owner",[986,1056,1057,1062],{},[1001,1058,1059],{},[31,1060,1061],{},"x",[1001,1063,1064],{},"Executable by owner",[986,1066,1067,1072],{},[1001,1068,1069],{},[31,1070,1071],{},"R",[1001,1073,1074],{},"Readable by world",[986,1076,1077,1081],{},[1001,1078,1079],{},[31,1080,892],{},[1001,1082,1083],{},"Writable by world",[986,1085,1086,1091],{},[1001,1087,1088],{},[31,1089,1090],{},"X",[1001,1092,1093],{},"Executable by world",[986,1095,1096,1101],{},[1001,1097,1098],{},[31,1099,1100],{},"L+size",[1001,1102,1103],{},"Larger than size (in bytes, or use k\u002FM\u002FG)",[986,1105,1106,1111],{},[1001,1107,1108],{},[31,1109,1110],{},"Lm+1",[1001,1112,1113],{},"Larger than 1MB",[986,1115,1116,1121],{},[1001,1117,1118],{},[31,1119,1120],{},"om",[1001,1122,1123],{},"Sort by modification time (oldest first)",[986,1125,1126,1131],{},[1001,1127,1128],{},[31,1129,1130],{},"Om",[1001,1132,1133],{},"Sort by modification time (newest first)",[986,1135,1136,1141],{},[1001,1137,1138],{},[31,1139,1140],{},"[1,5]",[1001,1142,1143],{},"Only first 5 matches",[986,1145,1146,1151],{},[1001,1147,1148],{},[31,1149,1150],{},"D",[1001,1152,1153],{},"Include dotfiles",[19,1155,1157],{"id":1156},"process-substitution","Process Substitution",[24,1159,1161],{"className":26,"code":1160,"language":28,"meta":29,"style":29},"# Compare two command outputs without temp files\ndiff \u003C(sort file1.txt) \u003C(sort file2.txt)\n\n# Feed multiple outputs to a command\ncat \u003C(echo \"Header\") \u003C(tail -n +2 data.csv) > output.csv\n\n# Process a file while reading it\nwhile read line; do\n  echo \"Processing: $line\"\ndone \u003C \u003C(grep \"ERROR\" app.log)\n",[31,1162,1163,1168,1193,1197,1202,1237,1241,1246,1261,1276],{"__ignoreMap":29},[34,1164,1165],{"class":36,"line":37},[34,1166,1167],{"class":40},"# Compare two command outputs without temp files\n",[34,1169,1170,1173,1176,1179,1182,1184,1186,1188,1191],{"class":36,"line":44},[34,1171,1172],{"class":706},"diff",[34,1174,1175],{"class":105}," \u003C(",[34,1177,1178],{"class":706},"sort",[34,1180,1181],{"class":51}," file1.txt",[34,1183,840],{"class":105},[34,1185,1175],{"class":105},[34,1187,1178],{"class":706},[34,1189,1190],{"class":51}," file2.txt",[34,1192,540],{"class":105},[34,1194,1195],{"class":36,"line":127},[34,1196,131],{"emptyLinePlaceholder":130},[34,1198,1199],{"class":36,"line":134},[34,1200,1201],{"class":40},"# Feed multiple outputs to a command\n",[34,1203,1204,1207,1209,1212,1215,1218,1221,1223,1226,1229,1231,1234],{"class":36,"line":140},[34,1205,1206],{"class":706},"cat",[34,1208,1175],{"class":105},[34,1210,1211],{"class":47},"echo",[34,1213,1214],{"class":105}," \"",[34,1216,1217],{"class":51},"Header",[34,1219,1220],{"class":105},"\")",[34,1222,1175],{"class":105},[34,1224,1225],{"class":706},"tail",[34,1227,1228],{"class":51}," -n +2 data.csv",[34,1230,840],{"class":105},[34,1232,1233],{"class":105}," >",[34,1235,1236],{"class":51}," output.csv\n",[34,1238,1239],{"class":36,"line":160},[34,1240,131],{"emptyLinePlaceholder":130},[34,1242,1243],{"class":36,"line":165},[34,1244,1245],{"class":40},"# Process a file while reading it\n",[34,1247,1248,1251,1254,1257,1259],{"class":36,"line":171},[34,1249,1250],{"class":685},"while",[34,1252,1253],{"class":47}," read",[34,1255,1256],{"class":51}," line",[34,1258,698],{"class":105},[34,1260,701],{"class":685},[34,1262,1263,1266,1268,1271,1274],{"class":36,"line":292},[34,1264,1265],{"class":47},"  echo",[34,1267,1214],{"class":105},[34,1269,1270],{"class":51},"Processing: ",[34,1272,1273],{"class":101},"$line",[34,1275,228],{"class":105},[34,1277,1278,1281,1284,1286,1289,1291,1294,1296,1299],{"class":36,"line":297},[34,1279,1280],{"class":685},"done",[34,1282,1283],{"class":105}," \u003C",[34,1285,1175],{"class":105},[34,1287,1288],{"class":706},"grep",[34,1290,1214],{"class":105},[34,1292,1293],{"class":51},"ERROR",[34,1295,116],{"class":105},[34,1297,1298],{"class":51}," app.log",[34,1300,540],{"class":105},[19,1302,1304],{"id":1303},"functions-and-scoping","Functions and Scoping",[24,1306,1308],{"className":26,"code":1307,"language":28,"meta":29,"style":29},"# Local variables are actually local\nfunction process_file() {\n  local filename=$1\n  local -i count=0     # integer type\n  local -a lines=()    # array type\n\n  while IFS= read -r line; do\n    lines+=($line)\n    ((count++))\n  done \u003C \"$filename\"\n\n  echo \"Processed $count lines\"\n}\n\n# Return values via echo or parameters\nfunction get_extension() {\n  local filename=$1\n  echo \"${filename##*.}\"\n}\n\next=$(get_extension \"document.pdf\")   # pdf\n",[31,1309,1310,1315,1329,1342,1360,1376,1380,1400,1411,1422,1436,1440,1456,1460,1464,1469,1480,1490,1508,1512,1516],{"__ignoreMap":29},[34,1311,1312],{"class":36,"line":37},[34,1313,1314],{"class":40},"# Local variables are actually local\n",[34,1316,1317,1320,1323,1326],{"class":36,"line":44},[34,1318,1319],{"class":739},"function",[34,1321,1322],{"class":47}," process_file",[34,1324,1325],{"class":105},"()",[34,1327,1328],{"class":105}," {\n",[34,1330,1331,1334,1337,1339],{"class":36,"line":127},[34,1332,1333],{"class":739},"  local",[34,1335,1336],{"class":101}," filename",[34,1338,106],{"class":105},[34,1340,1341],{"class":109},"$1\n",[34,1343,1344,1346,1349,1352,1354,1357],{"class":36,"line":134},[34,1345,1333],{"class":739},[34,1347,1348],{"class":51}," -i",[34,1350,1351],{"class":101}," count",[34,1353,106],{"class":105},[34,1355,452],{"class":1356},"sbssI",[34,1358,1359],{"class":40},"     # integer type\n",[34,1361,1362,1364,1367,1370,1373],{"class":36,"line":140},[34,1363,1333],{"class":739},[34,1365,1366],{"class":51}," -a",[34,1368,1369],{"class":101}," lines",[34,1371,1372],{"class":105},"=()",[34,1374,1375],{"class":40},"    # array type\n",[34,1377,1378],{"class":36,"line":160},[34,1379,131],{"emptyLinePlaceholder":130},[34,1381,1382,1385,1387,1389,1391,1394,1396,1398],{"class":36,"line":165},[34,1383,1384],{"class":685},"  while",[34,1386,743],{"class":101},[34,1388,106],{"class":105},[34,1390,1253],{"class":47},[34,1392,1393],{"class":51}," -r",[34,1395,1256],{"class":51},[34,1397,698],{"class":105},[34,1399,701],{"class":685},[34,1401,1402,1405,1407,1409],{"class":36,"line":171},[34,1403,1404],{"class":101},"    lines",[34,1406,578],{"class":105},[34,1408,1273],{"class":101},[34,1410,540],{"class":105},[34,1412,1413,1416,1419],{"class":36,"line":292},[34,1414,1415],{"class":105},"    ((",[34,1417,1418],{"class":101},"count",[34,1420,1421],{"class":105},"++))\n",[34,1423,1424,1427,1429,1431,1434],{"class":36,"line":297},[34,1425,1426],{"class":685},"  done",[34,1428,1283],{"class":105},[34,1430,1214],{"class":105},[34,1432,1433],{"class":101},"$filename",[34,1435,228],{"class":105},[34,1437,1438],{"class":36,"line":303},[34,1439,131],{"emptyLinePlaceholder":130},[34,1441,1442,1444,1446,1449,1452,1454],{"class":36,"line":316},[34,1443,1265],{"class":47},[34,1445,1214],{"class":105},[34,1447,1448],{"class":51},"Processed ",[34,1450,1451],{"class":101},"$count",[34,1453,1369],{"class":51},[34,1455,228],{"class":105},[34,1457,1458],{"class":36,"line":321},[34,1459,124],{"class":105},[34,1461,1462],{"class":36,"line":327},[34,1463,131],{"emptyLinePlaceholder":130},[34,1465,1466],{"class":36,"line":338},[34,1467,1468],{"class":40},"# Return values via echo or parameters\n",[34,1470,1471,1473,1476,1478],{"class":36,"line":343},[34,1472,1319],{"class":739},[34,1474,1475],{"class":47}," get_extension",[34,1477,1325],{"class":105},[34,1479,1328],{"class":105},[34,1481,1482,1484,1486,1488],{"class":36,"line":349},[34,1483,1333],{"class":739},[34,1485,1336],{"class":101},[34,1487,106],{"class":105},[34,1489,1341],{"class":109},[34,1491,1492,1494,1497,1500,1503,1505],{"class":36,"line":372},[34,1493,1265],{"class":47},[34,1495,1496],{"class":105}," \"${",[34,1498,1499],{"class":101},"filename",[34,1501,1502],{"class":105},"##*",[34,1504,250],{"class":51},[34,1506,1507],{"class":105},"}\"\n",[34,1509,1510],{"class":36,"line":377},[34,1511,124],{"class":105},[34,1513,1514],{"class":36,"line":383},[34,1515,131],{"emptyLinePlaceholder":130},[34,1517,1518,1521,1524,1527,1529,1532,1534,1536],{"class":36,"line":725},[34,1519,1520],{"class":101},"ext",[34,1522,1523],{"class":105},"=$(",[34,1525,1526],{"class":706},"get_extension",[34,1528,1214],{"class":105},[34,1530,1531],{"class":51},"document.pdf",[34,1533,116],{"class":105},[34,1535,840],{"class":105},[34,1537,1538],{"class":40},"   # pdf\n",[19,1540,1542],{"id":1541},"arithmetic-and-conditionals","Arithmetic and Conditionals",[24,1544,1546],{"className":26,"code":1545,"language":28,"meta":29,"style":29},"# Arithmetic expansion\nresult=$((42 * 13))\n((result++))           # No $ needed inside (( ))\n\n# Floating point (zsh only)\nresult=$((3.14 * 2))\n\n# Test operators\n[[ -f $file ]]         # file exists and is regular\n[[ -d $dir ]]          # directory exists\n[[ -s $file ]]         # file exists and is non-empty\n[[ -r $file ]]         # file is readable\n[[ -w $file ]]         # file is writable\n[[ -x $file ]]         # file is executable\n[[ -L $file ]]         # is symlink\n[[ $str == pattern* ]] # pattern matching\n[[ $str =~ regex ]]    # regex matching\n[[ $a -lt $b ]]        # numeric less than\n[[ $a -gt $b ]]        # numeric greater than\n[[ $a == $b ]]         # string equality\n[[ $a != $b ]]         # string inequality\n",[31,1547,1548,1553,1572,1585,1589,1594,1610,1614,1619,1636,1651,1665,1678,1692,1706,1720,1741,1758,1776,1792,1807],{"__ignoreMap":29},[34,1549,1550],{"class":36,"line":37},[34,1551,1552],{"class":40},"# Arithmetic expansion\n",[34,1554,1555,1558,1561,1564,1566,1569],{"class":36,"line":44},[34,1556,1557],{"class":101},"result",[34,1559,1560],{"class":105},"=$((",[34,1562,1563],{"class":706},"42",[34,1565,832],{"class":101},[34,1567,1568],{"class":1356}," 13",[34,1570,1571],{"class":105},"))\n",[34,1573,1574,1577,1579,1582],{"class":36,"line":127},[34,1575,1576],{"class":105},"((",[34,1578,1557],{"class":101},[34,1580,1581],{"class":105},"++))",[34,1583,1584],{"class":40},"           # No $ needed inside (( ))\n",[34,1586,1587],{"class":36,"line":134},[34,1588,131],{"emptyLinePlaceholder":130},[34,1590,1591],{"class":36,"line":140},[34,1592,1593],{"class":40},"# Floating point (zsh only)\n",[34,1595,1596,1598,1600,1603,1605,1608],{"class":36,"line":160},[34,1597,1557],{"class":101},[34,1599,1560],{"class":105},[34,1601,1602],{"class":706},"3.14",[34,1604,832],{"class":101},[34,1606,1607],{"class":1356}," 2",[34,1609,1571],{"class":105},[34,1611,1612],{"class":36,"line":165},[34,1613,131],{"emptyLinePlaceholder":130},[34,1615,1616],{"class":36,"line":171},[34,1617,1618],{"class":40},"# Test operators\n",[34,1620,1621,1624,1627,1630,1633],{"class":36,"line":292},[34,1622,1623],{"class":105},"[[",[34,1625,1626],{"class":105}," -f",[34,1628,1629],{"class":101}," $file ",[34,1631,1632],{"class":105},"]]",[34,1634,1635],{"class":40},"         # file exists and is regular\n",[34,1637,1638,1640,1643,1646,1648],{"class":36,"line":297},[34,1639,1623],{"class":105},[34,1641,1642],{"class":105}," -d",[34,1644,1645],{"class":101}," $dir ",[34,1647,1632],{"class":105},[34,1649,1650],{"class":40},"          # directory exists\n",[34,1652,1653,1655,1658,1660,1662],{"class":36,"line":303},[34,1654,1623],{"class":105},[34,1656,1657],{"class":105}," -s",[34,1659,1629],{"class":101},[34,1661,1632],{"class":105},[34,1663,1664],{"class":40},"         # file exists and is non-empty\n",[34,1666,1667,1669,1671,1673,1675],{"class":36,"line":316},[34,1668,1623],{"class":105},[34,1670,1393],{"class":105},[34,1672,1629],{"class":101},[34,1674,1632],{"class":105},[34,1676,1677],{"class":40},"         # file is readable\n",[34,1679,1680,1682,1685,1687,1689],{"class":36,"line":321},[34,1681,1623],{"class":105},[34,1683,1684],{"class":105}," -w",[34,1686,1629],{"class":101},[34,1688,1632],{"class":105},[34,1690,1691],{"class":40},"         # file is writable\n",[34,1693,1694,1696,1699,1701,1703],{"class":36,"line":327},[34,1695,1623],{"class":105},[34,1697,1698],{"class":105}," -x",[34,1700,1629],{"class":101},[34,1702,1632],{"class":105},[34,1704,1705],{"class":40},"         # file is executable\n",[34,1707,1708,1710,1713,1715,1717],{"class":36,"line":338},[34,1709,1623],{"class":105},[34,1711,1712],{"class":105}," -L",[34,1714,1629],{"class":101},[34,1716,1632],{"class":105},[34,1718,1719],{"class":40},"         # is symlink\n",[34,1721,1722,1724,1727,1730,1733,1735,1738],{"class":36,"line":343},[34,1723,1623],{"class":105},[34,1725,1726],{"class":101}," $str ",[34,1728,1729],{"class":105},"==",[34,1731,1732],{"class":101}," pattern",[34,1734,794],{"class":105},[34,1736,1737],{"class":105}," ]]",[34,1739,1740],{"class":40}," # pattern matching\n",[34,1742,1743,1745,1747,1750,1753,1755],{"class":36,"line":349},[34,1744,1623],{"class":105},[34,1746,1726],{"class":101},[34,1748,1749],{"class":105},"=~",[34,1751,1752],{"class":101}," regex ",[34,1754,1632],{"class":105},[34,1756,1757],{"class":40},"    # regex matching\n",[34,1759,1760,1762,1765,1768,1771,1773],{"class":36,"line":372},[34,1761,1623],{"class":105},[34,1763,1764],{"class":101}," $a ",[34,1766,1767],{"class":105},"-lt",[34,1769,1770],{"class":101}," $b ",[34,1772,1632],{"class":105},[34,1774,1775],{"class":40},"        # numeric less than\n",[34,1777,1778,1780,1782,1785,1787,1789],{"class":36,"line":377},[34,1779,1623],{"class":105},[34,1781,1764],{"class":101},[34,1783,1784],{"class":105},"-gt",[34,1786,1770],{"class":101},[34,1788,1632],{"class":105},[34,1790,1791],{"class":40},"        # numeric greater than\n",[34,1793,1794,1796,1798,1800,1802,1804],{"class":36,"line":383},[34,1795,1623],{"class":105},[34,1797,1764],{"class":101},[34,1799,1729],{"class":105},[34,1801,1770],{"class":101},[34,1803,1632],{"class":105},[34,1805,1806],{"class":40},"         # string equality\n",[34,1808,1809,1811,1813,1816,1818,1820],{"class":36,"line":725},[34,1810,1623],{"class":105},[34,1812,1764],{"class":101},[34,1814,1815],{"class":105},"!=",[34,1817,1770],{"class":101},[34,1819,1632],{"class":105},[34,1821,1822],{"class":40},"         # string inequality\n",[19,1824,1826],{"id":1825},"traps-and-cleanup","Traps and Cleanup",[24,1828,1830],{"className":26,"code":1829,"language":28,"meta":29,"style":29},"#!\u002Fusr\u002Fbin\u002Fenv zsh\nset -euo pipefail\n\ntmpdir=$(mktemp -d)\ntrap 'rm -rf \"$tmpdir\"' EXIT INT TERM\n\n# Your script logic here\necho \"Working in $tmpdir\"\n# ... do work ...\n\n# Cleanup happens automatically on exit or interrupt\n",[31,1831,1832,1836,1844,1848,1862,1885,1889,1894,1908,1913,1917],{"__ignoreMap":29},[34,1833,1834],{"class":36,"line":37},[34,1835,41],{"class":40},[34,1837,1838,1840,1842],{"class":36,"line":44},[34,1839,48],{"class":47},[34,1841,52],{"class":51},[34,1843,55],{"class":51},[34,1845,1846],{"class":36,"line":127},[34,1847,131],{"emptyLinePlaceholder":130},[34,1849,1850,1853,1855,1858,1860],{"class":36,"line":134},[34,1851,1852],{"class":101},"tmpdir",[34,1854,1523],{"class":105},[34,1856,1857],{"class":706},"mktemp",[34,1859,1642],{"class":51},[34,1861,540],{"class":105},[34,1863,1864,1867,1870,1873,1876,1879,1882],{"class":36,"line":140},[34,1865,1866],{"class":47},"trap",[34,1868,1869],{"class":105}," '",[34,1871,1872],{"class":51},"rm -rf \"$tmpdir\"",[34,1874,1875],{"class":105},"'",[34,1877,1878],{"class":51}," EXIT",[34,1880,1881],{"class":51}," INT",[34,1883,1884],{"class":51}," TERM\n",[34,1886,1887],{"class":36,"line":160},[34,1888,131],{"emptyLinePlaceholder":130},[34,1890,1891],{"class":36,"line":165},[34,1892,1893],{"class":40},"# Your script logic here\n",[34,1895,1896,1898,1900,1903,1906],{"class":36,"line":171},[34,1897,1211],{"class":47},[34,1899,1214],{"class":105},[34,1901,1902],{"class":51},"Working in ",[34,1904,1905],{"class":101},"$tmpdir",[34,1907,228],{"class":105},[34,1909,1910],{"class":36,"line":292},[34,1911,1912],{"class":40},"# ... do work ...\n",[34,1914,1915],{"class":36,"line":297},[34,1916,131],{"emptyLinePlaceholder":130},[34,1918,1919],{"class":36,"line":303},[34,1920,1921],{"class":40},"# Cleanup happens automatically on exit or interrupt\n",[19,1923,1925],{"id":1924},"reading-input-properly","Reading Input Properly",[24,1927,1929],{"className":26,"code":1928,"language":28,"meta":29,"style":29},"# Read file line by line (handles whitespace correctly)\nwhile IFS= read -r line; do\n  echo \"$line\"\ndone \u003C input.txt\n\n# Read with timeout\nif read -t 5 -p \"Continue? [Y\u002Fn] \" response; then\n  [[ $response =~ ^[Nn]$ ]] && exit 0\nfi\n\n# Read into array\nlines=(${(f)\"$(\u003Cfile.txt)\"})\n",[31,1930,1931,1936,1954,1964,1973,1977,1982,2013,2048,2053,2057,2062],{"__ignoreMap":29},[34,1932,1933],{"class":36,"line":37},[34,1934,1935],{"class":40},"# Read file line by line (handles whitespace correctly)\n",[34,1937,1938,1940,1942,1944,1946,1948,1950,1952],{"class":36,"line":44},[34,1939,1250],{"class":685},[34,1941,743],{"class":101},[34,1943,106],{"class":105},[34,1945,1253],{"class":47},[34,1947,1393],{"class":51},[34,1949,1256],{"class":51},[34,1951,698],{"class":105},[34,1953,701],{"class":685},[34,1955,1956,1958,1960,1962],{"class":36,"line":127},[34,1957,1265],{"class":47},[34,1959,1214],{"class":105},[34,1961,1273],{"class":101},[34,1963,228],{"class":105},[34,1965,1966,1968,1970],{"class":36,"line":134},[34,1967,1280],{"class":685},[34,1969,1283],{"class":105},[34,1971,1972],{"class":101}," input.txt\n",[34,1974,1975],{"class":36,"line":140},[34,1976,131],{"emptyLinePlaceholder":130},[34,1978,1979],{"class":36,"line":160},[34,1980,1981],{"class":40},"# Read with timeout\n",[34,1983,1984,1987,1989,1992,1995,1998,2000,2003,2005,2008,2010],{"class":36,"line":165},[34,1985,1986],{"class":685},"if",[34,1988,1253],{"class":47},[34,1990,1991],{"class":51}," -t",[34,1993,1994],{"class":1356}," 5",[34,1996,1997],{"class":51}," -p",[34,1999,1214],{"class":105},[34,2001,2002],{"class":51},"Continue? [Y\u002Fn] ",[34,2004,116],{"class":105},[34,2006,2007],{"class":51}," response",[34,2009,698],{"class":105},[34,2011,2012],{"class":685}," then\n",[34,2014,2015,2018,2021,2023,2026,2028,2031,2034,2037,2039,2042,2045],{"class":36,"line":171},[34,2016,2017],{"class":105},"  [[",[34,2019,2020],{"class":101}," $response ",[34,2022,1749],{"class":105},[34,2024,2025],{"class":101}," ^",[34,2027,487],{"class":105},[34,2029,2030],{"class":101},"Nn",[34,2032,2033],{"class":105},"]",[34,2035,2036],{"class":101},"$ ",[34,2038,1632],{"class":105},[34,2040,2041],{"class":105}," &&",[34,2043,2044],{"class":47}," exit",[34,2046,2047],{"class":1356}," 0\n",[34,2049,2050],{"class":36,"line":292},[34,2051,2052],{"class":685},"fi\n",[34,2054,2055],{"class":36,"line":297},[34,2056,131],{"emptyLinePlaceholder":130},[34,2058,2059],{"class":36,"line":303},[34,2060,2061],{"class":40},"# Read into array\n",[34,2063,2064,2067,2070,2073,2076,2079,2082],{"class":36,"line":316},[34,2065,2066],{"class":101},"lines",[34,2068,2069],{"class":105},"=(${",[34,2071,2072],{"class":101},"(f)",[34,2074,2075],{"class":105},"\"$(\u003C",[34,2077,2078],{"class":51},"file.txt",[34,2080,2081],{"class":105},")\"",[34,2083,2084],{"class":105},"})\n",[19,2086,2088],{"id":2087},"modifiers-quick-transformations","Modifiers: Quick Transformations",[24,2090,2092],{"className":26,"code":2091,"language":28,"meta":29,"style":29},"file=\"\u002Fhome\u002Fuser\u002Fdocuments\u002Farchive.tar.gz\"\n\n# Modifiers apply to parameter expansion\n${file:a}         # absolute path\n${file:t}         # basename (archive.tar.gz)\n${file:r}         # remove extension (archive.tar)\n${file:e}         # extension (gz)\n${file:h}         # head (directory path)\n${file:l}         # lowercase\n${file:u}         # uppercase\n${file:c}         # capitalized first letter\n\n# Chain modifiers\n${file:t:r}       # archive (basename without ext)\n",[31,2093,2094,2108,2112,2117,2133,2149,2164,2180,2196,2212,2228,2244,2248,2253],{"__ignoreMap":29},[34,2095,2096,2099,2101,2103,2106],{"class":36,"line":37},[34,2097,2098],{"class":101},"file",[34,2100,106],{"class":105},[34,2102,116],{"class":105},[34,2104,2105],{"class":51},"\u002Fhome\u002Fuser\u002Fdocuments\u002Farchive.tar.gz",[34,2107,228],{"class":105},[34,2109,2110],{"class":36,"line":44},[34,2111,131],{"emptyLinePlaceholder":130},[34,2113,2114],{"class":36,"line":127},[34,2115,2116],{"class":40},"# Modifiers apply to parameter expansion\n",[34,2118,2119,2121,2123,2125,2128,2130],{"class":36,"line":134},[34,2120,242],{"class":105},[34,2122,2098],{"class":101},[34,2124,174],{"class":105},[34,2126,2127],{"class":101},"a",[34,2129,366],{"class":105},[34,2131,2132],{"class":40},"         # absolute path\n",[34,2134,2135,2137,2139,2141,2144,2146],{"class":36,"line":140},[34,2136,242],{"class":105},[34,2138,2098],{"class":101},[34,2140,174],{"class":105},[34,2142,2143],{"class":101},"t",[34,2145,366],{"class":105},[34,2147,2148],{"class":40},"         # basename (archive.tar.gz)\n",[34,2150,2151,2153,2155,2157,2159,2161],{"class":36,"line":160},[34,2152,242],{"class":105},[34,2154,2098],{"class":101},[34,2156,174],{"class":105},[34,2158,1041],{"class":101},[34,2160,366],{"class":105},[34,2162,2163],{"class":40},"         # remove extension (archive.tar)\n",[34,2165,2166,2168,2170,2172,2175,2177],{"class":36,"line":165},[34,2167,242],{"class":105},[34,2169,2098],{"class":101},[34,2171,174],{"class":105},[34,2173,2174],{"class":101},"e",[34,2176,366],{"class":105},[34,2178,2179],{"class":40},"         # extension (gz)\n",[34,2181,2182,2184,2186,2188,2191,2193],{"class":36,"line":171},[34,2183,242],{"class":105},[34,2185,2098],{"class":101},[34,2187,174],{"class":105},[34,2189,2190],{"class":101},"h",[34,2192,366],{"class":105},[34,2194,2195],{"class":40},"         # head (directory path)\n",[34,2197,2198,2200,2202,2204,2207,2209],{"class":36,"line":292},[34,2199,242],{"class":105},[34,2201,2098],{"class":101},[34,2203,174],{"class":105},[34,2205,2206],{"class":101},"l",[34,2208,366],{"class":105},[34,2210,2211],{"class":40},"         # lowercase\n",[34,2213,2214,2216,2218,2220,2223,2225],{"class":36,"line":297},[34,2215,242],{"class":105},[34,2217,2098],{"class":101},[34,2219,174],{"class":105},[34,2221,2222],{"class":101},"u",[34,2224,366],{"class":105},[34,2226,2227],{"class":40},"         # uppercase\n",[34,2229,2230,2232,2234,2236,2239,2241],{"class":36,"line":303},[34,2231,242],{"class":105},[34,2233,2098],{"class":101},[34,2235,174],{"class":105},[34,2237,2238],{"class":101},"c",[34,2240,366],{"class":105},[34,2242,2243],{"class":40},"         # capitalized first letter\n",[34,2245,2246],{"class":36,"line":316},[34,2247,131],{"emptyLinePlaceholder":130},[34,2249,2250],{"class":36,"line":321},[34,2251,2252],{"class":40},"# Chain modifiers\n",[34,2254,2255,2257,2259,2261,2263,2265,2267,2269],{"class":36,"line":327},[34,2256,242],{"class":105},[34,2258,2098],{"class":101},[34,2260,174],{"class":105},[34,2262,2143],{"class":101},[34,2264,174],{"class":105},[34,2266,1041],{"class":101},[34,2268,366],{"class":105},[34,2270,2271],{"class":40},"       # archive (basename without ext)\n",[19,2273,2275],{"id":2274},"autoloading-and-module-system","Autoloading and Module System",[24,2277,2279],{"className":26,"code":2278,"language":28,"meta":29,"style":29},"# Create reusable functions in your fpath\n# ~\u002F.zsh\u002Ffunctions\u002Fmy-helpers\n\n# In .zshrc\nfpath+=(~\u002F.zsh\u002Ffunctions)\nautoload -Uz my-helpers\n\n# Functions in that directory can be lazy-loaded\n",[31,2280,2281,2286,2291,2295,2300,2312,2323,2327],{"__ignoreMap":29},[34,2282,2283],{"class":36,"line":37},[34,2284,2285],{"class":40},"# Create reusable functions in your fpath\n",[34,2287,2288],{"class":36,"line":44},[34,2289,2290],{"class":40},"# ~\u002F.zsh\u002Ffunctions\u002Fmy-helpers\n",[34,2292,2293],{"class":36,"line":127},[34,2294,131],{"emptyLinePlaceholder":130},[34,2296,2297],{"class":36,"line":134},[34,2298,2299],{"class":40},"# In .zshrc\n",[34,2301,2302,2305,2307,2310],{"class":36,"line":140},[34,2303,2304],{"class":101},"fpath",[34,2306,578],{"class":105},[34,2308,2309],{"class":51},"~\u002F.zsh\u002Ffunctions",[34,2311,540],{"class":105},[34,2313,2314,2317,2320],{"class":36,"line":160},[34,2315,2316],{"class":47},"autoload",[34,2318,2319],{"class":51}," -Uz",[34,2321,2322],{"class":51}," my-helpers\n",[34,2324,2325],{"class":36,"line":165},[34,2326,131],{"emptyLinePlaceholder":130},[34,2328,2329],{"class":36,"line":171},[34,2330,2331],{"class":40},"# Functions in that directory can be lazy-loaded\n",[19,2333,2335],{"id":2334},"a-complete-example","A Complete Example",[15,2337,2338],{},"Here's a real-world script I use to batch-process logs:",[24,2340,2342],{"className":26,"code":2341,"language":28,"meta":29,"style":29},"#!\u002Fusr\u002Fbin\u002Fenv zsh\nset -euo pipefail\n\nLOG_DIR=${1:-\u002Fvar\u002Flog\u002Fmyapp}\nDAYS_TO_KEEP=${2:-30}\nARCHIVE_DIR=${LOG_DIR}\u002Farchives\n\n# Ensure archive directory exists\nmkdir -p \"$ARCHIVE_DIR\"\n\n# Find and compress logs older than 7 days, but not already compressed\nfor log in $LOG_DIR\u002F*.log(N.m+7); do\n  [[ $log == *.gz ]] && continue\n\n  archive_name=\"${ARCHIVE_DIR}\u002F${log:t:r}-$(date -r $log +%Y%m%d).gz\"\n\n  echo \"Compressing: ${log:t} -> ${archive_name:t}\"\n  gzip -c \"$log\" > \"$archive_name\"\n  : > \"$log\"  # truncate original\n\ndone\n\n# Clean old archives\nfor archive in $ARCHIVE_DIR\u002F*.gz(N.m+$((DAYS_TO_KEEP - 7))); do\n  echo \"Removing old archive: ${archive:t}\"\n  rm \"$archive\"\ndone\n\necho \"Log rotation complete\"\n",[31,2343,2344,2348,2356,2360,2385,2400,2415,2419,2424,2438,2442,2447,2472,2493,2497,2550,2554,2587,2610,2626,2630,2634,2638,2643,2678,2699,2712,2717,2722],{"__ignoreMap":29},[34,2345,2346],{"class":36,"line":37},[34,2347,41],{"class":40},[34,2349,2350,2352,2354],{"class":36,"line":44},[34,2351,48],{"class":47},[34,2353,52],{"class":51},[34,2355,55],{"class":51},[34,2357,2358],{"class":36,"line":127},[34,2359,131],{"emptyLinePlaceholder":130},[34,2361,2362,2365,2367,2369,2372,2374,2376,2379,2381,2383],{"class":36,"line":134},[34,2363,2364],{"class":101},"LOG_DIR",[34,2366,106],{"class":105},[34,2368,110],{"class":109},[34,2370,2371],{"class":105},":-\u002F",[34,2373,416],{"class":101},[34,2375,189],{"class":105},[34,2377,2378],{"class":101},"log",[34,2380,189],{"class":105},[34,2382,197],{"class":101},[34,2384,124],{"class":109},[34,2386,2387,2390,2392,2395,2397],{"class":36,"line":140},[34,2388,2389],{"class":101},"DAYS_TO_KEEP",[34,2391,106],{"class":105},[34,2393,2394],{"class":109},"${2",[34,2396,113],{"class":105},[34,2398,2399],{"class":109},"30}\n",[34,2401,2402,2405,2408,2410,2412],{"class":36,"line":160},[34,2403,2404],{"class":101},"ARCHIVE_DIR",[34,2406,2407],{"class":105},"=${",[34,2409,2364],{"class":101},[34,2411,366],{"class":105},[34,2413,2414],{"class":51},"\u002Farchives\n",[34,2416,2417],{"class":36,"line":165},[34,2418,131],{"emptyLinePlaceholder":130},[34,2420,2421],{"class":36,"line":171},[34,2422,2423],{"class":40},"# Ensure archive directory exists\n",[34,2425,2426,2429,2431,2433,2436],{"class":36,"line":292},[34,2427,2428],{"class":706},"mkdir",[34,2430,1997],{"class":51},[34,2432,1214],{"class":105},[34,2434,2435],{"class":101},"$ARCHIVE_DIR",[34,2437,228],{"class":105},[34,2439,2440],{"class":36,"line":297},[34,2441,131],{"emptyLinePlaceholder":130},[34,2443,2444],{"class":36,"line":303},[34,2445,2446],{"class":40},"# Find and compress logs older than 7 days, but not already compressed\n",[34,2448,2449,2451,2454,2456,2459,2462,2464,2467,2470],{"class":36,"line":316},[34,2450,686],{"class":685},[34,2452,2453],{"class":101}," log ",[34,2455,692],{"class":685},[34,2457,2458],{"class":101}," $LOG_DIR",[34,2460,2461],{"class":51},"\u002F*.log",[34,2463,835],{"class":105},[34,2465,2466],{"class":706},"N.m+7",[34,2468,2469],{"class":105},");",[34,2471,701],{"class":685},[34,2473,2474,2476,2479,2481,2483,2486,2488,2490],{"class":36,"line":321},[34,2475,2017],{"class":105},[34,2477,2478],{"class":101}," $log ",[34,2480,1729],{"class":105},[34,2482,832],{"class":105},[34,2484,2485],{"class":101},".gz ",[34,2487,1632],{"class":105},[34,2489,2041],{"class":105},[34,2491,2492],{"class":685}," continue\n",[34,2494,2495],{"class":36,"line":327},[34,2496,131],{"emptyLinePlaceholder":130},[34,2498,2499,2502,2504,2506,2508,2510,2512,2514,2516,2518,2520,2522,2524,2526,2528,2531,2534,2537,2540,2543,2545,2548],{"class":36,"line":338},[34,2500,2501],{"class":101},"  archive_name",[34,2503,106],{"class":105},[34,2505,759],{"class":105},[34,2507,2404],{"class":101},[34,2509,366],{"class":105},[34,2511,189],{"class":51},[34,2513,242],{"class":105},[34,2515,2378],{"class":101},[34,2517,174],{"class":105},[34,2519,2143],{"class":101},[34,2521,174],{"class":105},[34,2523,1041],{"class":101},[34,2525,366],{"class":105},[34,2527,149],{"class":51},[34,2529,2530],{"class":105},"$(",[34,2532,2533],{"class":706},"date",[34,2535,2536],{"class":51}," -r ",[34,2538,2539],{"class":101},"$log",[34,2541,2542],{"class":51}," +%Y%m%d",[34,2544,840],{"class":105},[34,2546,2547],{"class":51},".gz",[34,2549,228],{"class":105},[34,2551,2552],{"class":36,"line":343},[34,2553,131],{"emptyLinePlaceholder":130},[34,2555,2556,2558,2560,2563,2565,2567,2569,2571,2573,2576,2578,2581,2583,2585],{"class":36,"line":349},[34,2557,1265],{"class":47},[34,2559,1214],{"class":105},[34,2561,2562],{"class":51},"Compressing: ",[34,2564,242],{"class":105},[34,2566,2378],{"class":101},[34,2568,174],{"class":105},[34,2570,2143],{"class":101},[34,2572,366],{"class":105},[34,2574,2575],{"class":51}," -> ",[34,2577,242],{"class":105},[34,2579,2580],{"class":101},"archive_name",[34,2582,174],{"class":105},[34,2584,2143],{"class":101},[34,2586,1507],{"class":105},[34,2588,2589,2592,2595,2597,2599,2601,2603,2605,2608],{"class":36,"line":372},[34,2590,2591],{"class":706},"  gzip",[34,2593,2594],{"class":51}," -c",[34,2596,1214],{"class":105},[34,2598,2539],{"class":101},[34,2600,116],{"class":105},[34,2602,1233],{"class":105},[34,2604,1214],{"class":105},[34,2606,2607],{"class":101},"$archive_name",[34,2609,228],{"class":105},[34,2611,2612,2615,2617,2619,2621,2623],{"class":36,"line":377},[34,2613,2614],{"class":47},"  :",[34,2616,1233],{"class":105},[34,2618,1214],{"class":105},[34,2620,2539],{"class":101},[34,2622,116],{"class":105},[34,2624,2625],{"class":40},"  # truncate original\n",[34,2627,2628],{"class":36,"line":383},[34,2629,131],{"emptyLinePlaceholder":130},[34,2631,2632],{"class":36,"line":725},[34,2633,722],{"class":685},[34,2635,2636],{"class":36,"line":730},[34,2637,131],{"emptyLinePlaceholder":130},[34,2639,2640],{"class":36,"line":736},[34,2641,2642],{"class":40},"# Clean old archives\n",[34,2644,2645,2647,2650,2652,2655,2658,2660,2663,2666,2669,2671,2674,2676],{"class":36,"line":751},[34,2646,686],{"class":685},[34,2648,2649],{"class":101}," archive ",[34,2651,692],{"class":685},[34,2653,2654],{"class":101}," $ARCHIVE_DIR",[34,2656,2657],{"class":51},"\u002F*.gz",[34,2659,835],{"class":105},[34,2661,2662],{"class":706},"N.m+$((DAYS_TO_KEEP",[34,2664,2665],{"class":51}," -",[34,2667,2668],{"class":1356}," 7",[34,2670,840],{"class":105},[34,2672,2673],{"class":101},"))",[34,2675,698],{"class":105},[34,2677,701],{"class":685},[34,2679,2681,2683,2685,2688,2690,2693,2695,2697],{"class":36,"line":2680},25,[34,2682,1265],{"class":47},[34,2684,1214],{"class":105},[34,2686,2687],{"class":51},"Removing old archive: ",[34,2689,242],{"class":105},[34,2691,2692],{"class":101},"archive",[34,2694,174],{"class":105},[34,2696,2143],{"class":101},[34,2698,1507],{"class":105},[34,2700,2702,2705,2707,2710],{"class":36,"line":2701},26,[34,2703,2704],{"class":706},"  rm",[34,2706,1214],{"class":105},[34,2708,2709],{"class":101},"$archive",[34,2711,228],{"class":105},[34,2713,2715],{"class":36,"line":2714},27,[34,2716,722],{"class":685},[34,2718,2720],{"class":36,"line":2719},28,[34,2721,131],{"emptyLinePlaceholder":130},[34,2723,2725,2727,2729,2732],{"class":36,"line":2724},29,[34,2726,1211],{"class":47},[34,2728,1214],{"class":105},[34,2730,2731],{"class":51},"Log rotation complete",[34,2733,228],{"class":105},[19,2735,2737],{"id":2736},"key-takeaways","Key Takeaways",[2739,2740,2741,2751,2760,2773,2789,2801],"ol",{},[60,2742,2743,2750],{},[2744,2745,2746,2747],"strong",{},"Always use ",[31,2748,2749],{},"set -euo pipefail"," — catches errors early",[60,2752,2753,2759],{},[2744,2754,2755,2756,2758],{},"Use ",[31,2757,740],{}," in functions"," — prevents variable pollution",[60,2761,2762,2772],{},[2744,2763,2764,2765,2768,2769],{},"Prefer ",[31,2766,2767],{},"[[ ]]"," over ",[31,2770,2771],{},"[ ]"," — safer, more features",[60,2774,2775,2778,2779,2782,2783,2782,2786],{},[2744,2776,2777],{},"Glob qualifiers are your friend"," — ",[31,2780,2781],{},"(.)",", ",[31,2784,2785],{},"(\u002F)",[31,2787,2788],{},"(om[1,5])",[60,2790,2791,2778,2794,2797,2798],{},[2744,2792,2793],{},"Parameter expansion is faster than external commands",[31,2795,2796],{},"${var##*\u002F}"," vs ",[31,2799,2800],{},"basename",[60,2802,2803,2810],{},[2744,2804,2755,2805,2807,2808],{},[31,2806,1857],{}," + ",[31,2809,1866],{}," — never leave temp files behind",[19,2812,2814],{"id":2813},"resources","Resources",[57,2816,2817,2823,2829,2835],{},[60,2818,2819,2822],{},[31,2820,2821],{},"man zshall"," — The complete reference",[60,2824,2825,2828],{},[31,2826,2827],{},"man zshexpn"," — Parameter expansion details",[60,2830,2831,2834],{},[31,2832,2833],{},"man zshcompwid"," — Completion system",[60,2836,2837,2843],{},[2127,2838,2842],{"href":2839,"rel":2840},"https:\u002F\u002Fzshwiki.org",[2841],"nofollow","Zsh Wiki"," — Community patterns",[2845,2846,2847],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":29,"searchDepth":44,"depth":44,"links":2849},[2850,2851,2856,2857,2860,2861,2862,2863,2864,2865,2866,2867,2868,2869],{"id":21,"depth":44,"text":22},{"id":80,"depth":44,"text":81,"children":2852},[2853,2854,2855],{"id":85,"depth":127,"text":86},{"id":207,"depth":127,"text":208},{"id":405,"depth":127,"text":406},{"id":515,"depth":44,"text":516},{"id":770,"depth":44,"text":771,"children":2858},[2859],{"id":977,"depth":127,"text":978},{"id":1156,"depth":44,"text":1157},{"id":1303,"depth":44,"text":1304},{"id":1541,"depth":44,"text":1542},{"id":1825,"depth":44,"text":1826},{"id":1924,"depth":44,"text":1925},{"id":2087,"depth":44,"text":2088},{"id":2274,"depth":44,"text":2275},{"id":2334,"depth":44,"text":2335},{"id":2736,"depth":44,"text":2737},{"id":2813,"depth":44,"text":2814},{"title":2871,"description":2872,"buttonText":2873,"buttonUrl":2874},"Need help automating your workflow?","I build custom CLI tools and automation scripts that save hours of manual work.","Let's Talk","\u002Fcontact","2026-04-22","A practical guide to zsh scripting covering parameter expansion, globbing, process substitution, and advanced patterns you actually need.",false,"md",{},{"component":2881,"props":2882},"NeoTokyo.takumi",{"title":2883,"description":2884},"Zsh Scripting Cheatsheet","Advanced patterns for shell automation","\u002Fguides\u002Fzsh-scripting-cheatsheet","8 minutes","index, follow",[2889],{"@type":2890,"headline":6,"description":2891,"author":2892},"TechArticle","A practical guide to zsh scripting covering parameter expansion, globbing, and advanced patterns",{"@type":2893,"name":2894},"Person","Cesar Valadez",{"title":6,"description":2876,"robots":2887},{"loc":2885,"lastmod":2875,"changefreq":2897,"priority":2898},"monthly",0.8,"guides\u002Fzsh-scripting-cheatsheet",[28,2901,2902,2903,2904],"scripting","shell","automation","cli","juPrqZI1vZmBFXFWDFD81DBjpgirJog8FZ3dyPs9gm4",1777186590704]