lcomma() { sed '
$x;$G;/\(.*\),/!H;//!{$!d
}; $!x;$s//\1/;s/^\n//'
}
Bu ,, herhangi bir giriş dosyasındaki a'nın son tekrarını kaldırmalıdır ve a'nın ,oluşmadığı dosyaları da yazdırır . Temel olarak, virgül içermeyen çizgi dizilerini tamponlar.
Bu virgül karşılaştığında tutma tamponu ile ve bu şekilde aynı zamanda, son virgül itibaren meydana gelen tüm satırları yazdırır içinde mevcut hat tamponu değiştirir ve onun tutma tampon serbest bırakır.
Sadece geçmiş dosyamı inceliyordum ve bunu buldum:
lmatch(){ set "USAGE:\
lmatch /BRE [-(((s|-sub) BRE)|(r|-ref)) REPL [-(f|-flag) FLAG]*]*
" "${1%"${1#?}"}" "$@"
eval "${ZSH_VERSION:+emulate sh}"; eval '
sed " 1x; \\$3$2!{1!H;\$!d
}; \\$3$2{x;1!p;\$!d;x
}; \\$3$2!x;\\$3$2!b'"
$( unset h;i=3 p=:-:shfr e='\033[' m=$(($#+1)) f=OPTERR
[ -t 2 ] && f=$e\2K$e'1;41;17m}\r${h-'$f$e\0m
f='\${$m?"\"${h-'$f':\t\${$i$e\n}\$1\""}\\c' e=} _o=
o(){ IFS=\ ;getopts $p a "$1" &&
[ -n "${a#[?:]}" ] &&
o=${a#-}${OPTARG-${1#-?}} ||
! eval "o=$f;o=\${o%%*\{$m\}*}"
}; a(){ case ${a#[!-]}$o in (?|-*) a=;;esac; o=
set $* "${3-$2$}{$((i+=!${#a}))${a:+#-?}}"\
${3+$2 "{$((i+=1))$e"} $2
IFS=$; _o=${_o%"${3+$_o} "*}$*\
}; while eval "o \"\${$((i+=(OPTIND=1)))}\""
do case ${o#[!$a]} in
(s*|ub) a s 2 '' ;;
(r*|ef) a s 2 ;;
(f*|lag) a ;;
(h*|elp) h= o; break ;;
esac; done; set -f; printf "\t%b\n\t" $o $_o
)\"";}
Aslında oldukça iyi. Evet, kullanır eval, ancak argümanlarına sayısal bir referansın ötesinde hiçbir şey iletmez. sedSon eşleşmeyi işlemek için rasgele komut dosyaları oluşturur . Sana göstereceğim:
printf "%d\" %d' %d\" %d'\n" $(seq 5 5 200) |
tee /dev/fd/2 |
lmatch d^.0 \ #all re's delimit w/ d now
-r '&&&&' \ #-r or --ref like: '...s//$ref/...'
--sub \' sq \ #-s or --sub like: '...s/$arg1/$arg2/...'
--flag 4 \ #-f or --flag appended to last -r or -s
-s\" \\dq \ #short opts can be '-s $arg1 $arg2' or '-r$arg1'
-fg #tacked on so: '...s/"/dq/g...'
Bu stderr için aşağıdaki yazdırır. Bu, lmatchgirdisinin bir kopyasıdır :
5" 10' 15" 20'
25" 30' 35" 40'
45" 50' 55" 60'
65" 70' 75" 80'
85" 90' 95" 100'
105" 110' 115" 120'
125" 130' 135" 140'
145" 150' 155" 160'
165" 170' 175" 180'
185" 190' 195" 200'
İşlevin evaled alt kabuğu, tüm bağımsız değişkenleri bir kez yineler. Onlar üzerinde yürürken, her bir anahtarın içeriğine bağlı olarak uygun bir sayaç yineler ve bir sonraki yineleme için bu birçok argümanı atlar. O andan itibaren, argüman başına birkaç şeyden birini yapar:
- Her seçenek için opsiyon ayrıştırıcı ekler
$aiçin $o. $adeğeri, $iişlenen her arg için arg sayısı ile artırılan değere göre atanır . $a, aşağıdaki iki değerden birine atanır:
a=$((i+=1)) - kısa seçeneklerden birinin argümanı kendisine eklenmemişse veya seçenek uzunsa bu atanır.
a=$i#-?- seçenek kısa biridir ve eğer bu atanır gelmez onun arg kendisine eklenmiş olması.
a=\${$a}${1:+$d\${$(($1))\}}- İlk atamadan bağımsız olarak, $adeğeri her zaman parantez içine alınır ve - bir -sdurumda - bazen $ibir kez daha artırılır ve ek olarak sınırlandırılmış alan eklenir.
Sonuç olarak, evalbilinmeyenleri içeren bir dize asla geçirilmez. Komut satırı bağımsız değişkenlerinin her birine sayısal bağımsız değişken numaraları denir - hatta ilk bağımsız değişkenin ilk karakterinden ayıklanan ve kaçınılmaz olan karakteri kullanmanız gereken tek zamandır. Temelde, fonksiyon makro jeneratör - herhangi özel bir şekilde argümanların değerleri yorumladığı çünkü hiçbir zaman sedteneke (ve tabii ki olacak) kolaylıkla senaryoyu ayrıştırır zaman hallederim. Bunun yerine, argümanlarını mantıklı bir şekilde çalıştırılabilir bir senaryoda düzenler.
İşte işlevin bazı hata ayıklama çıktısı:
... sed " 1x;\\$2$1!{1!H;\$!d
}; \\$2$1{x;1!p;\$!d;x
}; \\$2$1!x;\\$2$1!b
s$1$1${4}$1
s$1${6}$1${7}$1${9}
s$1${10#-?}$1${11}$1${12#-?}
"
++ sed ' 1x;\d^.0d!{1!H;$!d
}; \d^.0d{x;1!p;$!d;x
}; \d^.0d!x;\d^.0d!b
sdd&&&&d
sd'\''dsqd4
sd"d\dqdg
'
Ve böylece lmatchbir dosyadaki son eşleşmeyi takiben verilere normal ifadeleri kolayca uygulamak için kullanılabilir. Yukarıda çalıştırdığım komutun sonucu:
5" 10' 15" 20'
25" 30' 35" 40'
45" 50' 55" 60'
65" 70' 75" 80'
85" 90' 95" 100'
101010105dq 110' 115dq 120'
125dq 130' 135dq 140sq
145dq 150' 155dq 160'
165dq 170' 175dq 180'
185dq 190' 195dq 200'
... son kez /^.0/izlenen dosya girdisinin alt kümesi eşleştiğinde aşağıdaki ikameleri uygular:
sdd&&&&d- yerine $match4 kez geçer .
sd'dsqd4 - son maçtan bu yana hattın başlangıcını takip eden dördüncü tek tırnak.
sd"d\dqd2 - Aynen, ama çift tırnak ve küresel için.
Ve böylece, lmatchbir dosyadaki son virgül kaldırmak için nasıl kullanılabileceğini göstermek için:
printf "%d, %d %d, %d\n" $(seq 5 5 100) |
lmatch '/\(.*\),' -r\\1
ÇIKTI:
5, 10 15, 20
25, 30 35, 40
45, 50 55, 60
65, 70 75, 80
85, 90 95 100