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