Не работает на меня с обратными косыми чертами, но я могу объяснить этого Вам:
echo "$PATH" | awk 'NF && !x[$0]++' RS='[:|\n]'
Разделитель записей (RS
) установлен на один из символов ": |" и новая строка. $PATH
обычно всего одна строка с элементами, разделенными ":". Это заставляет awk вести себя как пути, не были разделены ":" но каждый на его собственной строке.
NF
средства, что пустые строки (NF == 0
) проигнорированы. x
ассоциативный массив с путями как нижний индекс. !x[$0]++
средства, что "строка" проигнорирована если x[$0]
больше, чем 0. Результат состоит в том, что каждая строка производится только однажды. Во время первого показа x[$0]
увеличен так, чтобы в следующих выполнениях !x[$0]
ложь.
Этот пример показывает частоту всех элементов после того, как последняя строка была обработана:
echo "a:b:a:c:a:b" |
awk 'NF && !x[$0]++;END {for (var in x) print var ": " x[var]}' RS='[:|\n]'
a
b
c
a: 3
b: 2
c: 1
Как описано Hauke намерение здесь состоит в том, чтобы только иметь уникальные элементы в $PATH
переменная.
Это не портативный awk сценарий хотя, RS
часто ограничивается только отдельным символом и не регулярным выражением. Более портативная альтернатива была бы чем-то вроде этого:
setenv PATH `printf "%s" "$PATH" | awk '{ sub("/$","") }; x[$0]++ < 1' RS=: | paste -s -d : -`
Протестированный в tcsh с простофилей и nawk.
Несколько вещей отметить:
printf
.!
, то, что означает расширение истории на tcsh, может быть заменено путем проверки, является ли значение меньше чем 1.sub()
.tcsh
, можно сделать set -f path=($path)
хотя (f
для первого).
– Stéphane Chazelas
20.05.2013, 00:05