Вы можете использовать ассоциативный массив, который вводится в значение столбца, присваивая значения только из третьей записи (строки )и далее(NR>2
):
$ awk 'NR>2 {count[$1]++} END {for (i in count) print i, count[i]}' 1.txt
1 1
2 2
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 2
12 1
13 1
14 2
15 5
16 1
17 1
Обратите внимание, что порядок обхода массива не гарантируется. -вам может понадобиться дополнительная сортировка, если важен порядок вывода.
Трубка через cut -d \\ -f 4-
.
echo 'hku\test\user\software\microsoft\windows\currentversion\runonce\delete cached update binary' | cut -d \\ -f 4-
Урожайность:
software\microsoft\windows\currentversion\runonce\delete cached update binary
Обратите внимание на двойной \\
, так как одиночный \
является escape-символом.
Сsed
:
sed -E 's/^([^\]*[\]){3}//' infile
или то же самое вawk
:
awk '{ sub(/([^\\]*[\\]){3}/, "") }1' infile
Совпадение повторяется из (regex)
3 раза; [^\]*[\]
соответствует нулю -или -больше любых -символов, но не обратной -косой черте (и не новой строке, в исключительных случаях ), за которой следует обратная -косая черта.
И оболочка (POSIX sh/bash/Korn/zsh )решение:
$ str='hku\test\user\software\microsoft\windows\currentversion\runonce\delete cached update binary'
$ for i in $(seq 3); do str="${str#*\\}"; done
$ printf '%s\n' "$str"
Синтаксис ${parameter#word}
представляет собой расширение параметра , которое удаляет самый короткий префикс из своего параметра.
Использованиеawk
:
awk 'BEGIN{FS=OFS="\\"; }{for(i=4;i<NF;i++) printf "%s", $i OFS; print $NF }' input
Поскольку мы хотим напечатать все после 3-го символа \
, разделитель полей FS
и разделитель выходных полей OFS
установлены на \
. FS="\\"
, потому что одиночный \
является escape-символом. Поскольку \
теперь является разделителем полей, мы используем цикл for для печати от поля номер 4 до последнего поля записи.
Или вот так:
awk 'BEGIN{FS=OFS="\\"; }{for(i=4;i<=NF;i++) printf "%s", $i (i==NF?ORS:OFS) }' input
Здесь все то же самое, но используется тернарный оператор. Здесь цикл for будет печатать OFS
после $i
для всех полей, кроме последнего. После последнего поля будет напечатано ORS
, то есть новая строка.
Другой метод:
awk 'BEGIN{OFS="\\"} { n=split($0,arr,OFS); $0=""; for (i=4; i<=n; ++i) $(i-3)=arr[i]; print }' input
Здесь split()
встроенная функция -разделяет $0
на OFS
и создает массив arr
. Затем цикл for изменяет каждое поле записи на $(i-3)=arr[i]
. Например, для первого элемента цикла for $1
будет arr[4]. Почему $1
, потому что $(4-3)
— это $1
. Когда цикл завершен, awk
имеет новый $0
, который начинается с четвертого поля старой записи($0
). Затем команда печати печатает новый $0
.
awk -F"\\" '{ OFS="\\"; $1=$2=$3=""; sub(/\\*/,""); print }' filename
выход
software\microsoft\windows\currentversion\runonce\delete cached update binary
Лишь бы не промахнутьсяperl
:
perl -e '@a=split /\\/, $ARGV[0]; print(join("\\", splice @a, 3), "\n")' $str
Где str
— путь.
Или без окончания новой строки:
perl -e '@a=split /\\/, $ARGV[0]; print join "\\", splice @a, 3' $str
## input variables
n=3
s='hku\test\user\software\microsoft\windows\currentversion\runonce\delete cached update binary'
сед Измените n --ю обратную косую черту на новую строку, символ, который, как известно, не присутствует, затем мы удаляем все до новой строки.
printf '%s\n' "$s" |
sed -e '
s/\\/\n/'"$n"'
s/.*\n//
' -
software\microsoft\windows\currentversion\runonce\delete cached update binary
командная строка Linux Преобразуйте в одно -поле на строку, отрежьте первые n полей, а затем соедините их обратно.
printf '%s\n' "$s" | tr '\\' '\n' | tail -n+"$((n+1))" | paste -sd '\\' -
встроенные функции bash
set -f;IFS=\\;
declare -a a=( $s )
printf '%s\n' "${a[*]:$n}"
авк
printf '%s\n' "$s" |
awk -F '\' -v n="$n" '
NF>n {
for (i=p=1; i<=n; i++)
p += 1+length($i)
$0 = substr($0,p)
}1' -
printf '%s\n' "$s" |
perl -pals -F'/\\/,$_,$n+1' -e '
$_=$F[-1];
' -- -n="$n" -
python3 -c 'import sys
p,(s,n) = -1,sys.argv[1:]
for i in range(1+int(n)):
p = 1+s.find("\\",p)
print(s[p:])
' "$s" "$n"