Вы можете использоватьawk
:
awk 'BEGIN{filename=0};$0 ~ /^........20....$/{filename++};{print >> "file"filename}' input_file
При предоставленных входных данных будет получено:
file1
:
0000000020DTL0
00000000510000
00000000520000
00000000530000
00000000510000
00000000520000
00000000530000
00000000800000
file2
:
0000000020DTL0
00000000510730
00000000520000
0000000053 000
00000000510000
00000000520000
00000000530000
00000000800000
Если я правильно понял, вы ищете что-то вроде этого:
$ var=hello
$ while [ -n "$var" ]; do
printf -- "Var is now '%s'\n" "$var"
var=$(printf -- '%s\n' "$var" | cut -c2-);
done
Var is now 'hello'
Var is now 'ello'
Var is now 'llo'
Var is now 'lo'
Var is now 'o'
Кажется, это работает:
foo() { [[ ! "${#1}" -eq 1 ]] && printf "%s" "$1" | cut -c2-; }
bar="hello"
while [[ ! -z $(foo "$bar") ]]; do bar=$(foo "$bar"); printf "%s\n" "$bar"; done
ello
llo
lo
o
Вы можете сделать это с помощью рекурсии:
command1() {
local var
IFS= read -r var
if [[ $var ]]; then
printf '%s\n' "$var"
cut -c2- <<< "$var" | "${FUNCNAME[0]}"
fi
}
Тогда:
$ echo hello | command1
hello
ello
llo
lo
o
Это действительно работает в Linux:
echo hello | tee /dev/fd/0
hello
hello
hello
...
echo hello | gawk '!length{exit(0)} {print; print substr($0,2) >"/dev/fd/3"; fflush()}' 3>/dev/fd/0
hello
ello
llo
lo
o
Это использует тот факт, что в Linux все каналы на самом деле являются именованными каналами (, т. е. они могут быть открыты через путь ). Используя обычный именованный канал, он будет работать и в других системах Unix, --см. этот ответ на Stackoverflow.