多次重复文字
repeating the text many times
我想重复输入文本 5 次,并想在另一个文本中保存 file.However 在每次重复中,第一行和最后一行的行号只被更改。
我的输入文字是:
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
输出:
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
READ 2 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 2A ALL
READ 3 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 3A ALL
READ 4 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 4A ALL
READ 5 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 5A ALL
我试过了
#!/bin/sh
for file in `cat input.txt`
do
yes $file
done
使用 GNU awk gensub()
:
$ awk -v RS= -v ORS='\n\n' '{for (i=1; i<=5; i++) print gensub(/1/,i,"g")}' file
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
READ 2 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 2A ALL
READ 3 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 3A ALL
READ 4 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 4A ALL
READ 5 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 5A ALL
for file in `cat input.txt`
循环输入文件中的单词。
yes $file
将永远输出单词,因此您的循环将永远不会重复。
使用 for
循环将索引从 1 递增到 5。然后使用 sed
将其替换到文件的第一行和最后一行。
for i in {1..5}; do
sed -e "s/(READ ).*( ALL)/\1$i\2/" -e "s/(WRITE ).*(A ALL)/\1$i\2/" input.txt
done
你可以用 Perl 做到这一点:
echo 'READ %s ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE %sA ALL' | perl -0777 -nE '
for($x=1; $x<=5; $x++) { say sprintf $_, $x, $x }'
或者在 awk 中:
echo 'READ %s ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE %sA ALL' | awk -v RS= '{for(i=1;i<=5;i++) printf([=11=] "\n\n",i,i)}'
shell中的相同概念:
s='READ %s ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE %sA ALL'
for i in {1..5}; do
printf "$s\n\n" "$i" "$i"
done
如果您不想为 printf
创建模板以与 %s
一起用于您的替换,我会使用 perl 以获得更精确的可用正则表达式:
echo 'READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL' | perl -0777 -nE '
for($x=1; $x<=5; $x++) {
$s=$_;
$s=~s/^(READ |WRITE )(1)(?=\D|$)/$x/g;
say $s }'
假设您只想替换字符串中第一个和最后一个1
,这是一个gnu-awk解决方案:
awk -v RS= '
{
print
for (i=2; i<=5; ++i)
print gensub(/^([^1]*)1(.*)1([^1]*)$/, "\1" i "\2" i "\3", "1")
}' ORS='\n\n' file
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
READ 2 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 2A ALL
READ 3 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 3A ALL
READ 4 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 4A ALL
READ 5 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 5A ALL
不使用除 Bash 以外的任何程序/进程:
repeat_file() {
local -ir times=""
local -a lines first_line last_line
readarray -t lines
((${#lines[@]} >= 2)) || return 2
read -a first_line <<<"${lines[0]}"
read -a last_line <<<"${lines[-1]}"
unset 'lines[-1]'
unset 'lines[0]'
local -ar lines
local -i idx
local line
for ((idx = 1;;)); do
echo "${first_line[@]}"
for line in "${lines[@]}"; do
echo "${line}"
done
echo "${last_line[@]}"
((++idx > times)) && break
((++first_line[1]))
last_line[1]="$(("${last_line[1]%A}" + 1))A"
echo
done
}
repeat_file 5 < input > output
另一个 Perl 解决方案:
更新答案(感谢 dawg)
echo 'READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL' | perl -0777 -nE 'while($i++<5) { s/(\d)(?=A? ALL)/$i/g; say }'
原回答
$ echo 'READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL' | perl -0777 -nE ' $_.="\n"; print;
while($i++<=3) { s/(\d)(?=A? ALL)/+1/ge; print } '
同时打印:
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
READ 2 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 2A ALL
READ 3 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 3A ALL
READ 4 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 4A ALL
READ 5 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 5A ALL
我想重复输入文本 5 次,并想在另一个文本中保存 file.However 在每次重复中,第一行和最后一行的行号只被更改。
我的输入文字是:
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
输出:
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
READ 2 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 2A ALL
READ 3 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 3A ALL
READ 4 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 4A ALL
READ 5 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 5A ALL
我试过了
#!/bin/sh
for file in `cat input.txt`
do
yes $file
done
使用 GNU awk gensub()
:
$ awk -v RS= -v ORS='\n\n' '{for (i=1; i<=5; i++) print gensub(/1/,i,"g")}' file
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
READ 2 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 2A ALL
READ 3 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 3A ALL
READ 4 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 4A ALL
READ 5 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 5A ALL
for file in `cat input.txt`
循环输入文件中的单词。
yes $file
将永远输出单词,因此您的循环将永远不会重复。
使用 for
循环将索引从 1 递增到 5。然后使用 sed
将其替换到文件的第一行和最后一行。
for i in {1..5}; do
sed -e "s/(READ ).*( ALL)/\1$i\2/" -e "s/(WRITE ).*(A ALL)/\1$i\2/" input.txt
done
你可以用 Perl 做到这一点:
echo 'READ %s ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE %sA ALL' | perl -0777 -nE '
for($x=1; $x<=5; $x++) { say sprintf $_, $x, $x }'
或者在 awk 中:
echo 'READ %s ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE %sA ALL' | awk -v RS= '{for(i=1;i<=5;i++) printf([=11=] "\n\n",i,i)}'
shell中的相同概念:
s='READ %s ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE %sA ALL'
for i in {1..5}; do
printf "$s\n\n" "$i" "$i"
done
如果您不想为 printf
创建模板以与 %s
一起用于您的替换,我会使用 perl 以获得更精确的可用正则表达式:
echo 'READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL' | perl -0777 -nE '
for($x=1; $x<=5; $x++) {
$s=$_;
$s=~s/^(READ |WRITE )(1)(?=\D|$)/$x/g;
say $s }'
假设您只想替换字符串中第一个和最后一个1
,这是一个gnu-awk解决方案:
awk -v RS= '
{
print
for (i=2; i<=5; ++i)
print gensub(/^([^1]*)1(.*)1([^1]*)$/, "\1" i "\2" i "\3", "1")
}' ORS='\n\n' file
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
READ 2 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 2A ALL
READ 3 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 3A ALL
READ 4 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 4A ALL
READ 5 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 5A ALL
不使用除 Bash 以外的任何程序/进程:
repeat_file() {
local -ir times=""
local -a lines first_line last_line
readarray -t lines
((${#lines[@]} >= 2)) || return 2
read -a first_line <<<"${lines[0]}"
read -a last_line <<<"${lines[-1]}"
unset 'lines[-1]'
unset 'lines[0]'
local -ar lines
local -i idx
local line
for ((idx = 1;;)); do
echo "${first_line[@]}"
for line in "${lines[@]}"; do
echo "${line}"
done
echo "${last_line[@]}"
((++idx > times)) && break
((++first_line[1]))
last_line[1]="$(("${last_line[1]%A}" + 1))A"
echo
done
}
repeat_file 5 < input > output
另一个 Perl 解决方案:
更新答案(感谢 dawg)
echo 'READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL' | perl -0777 -nE 'while($i++<5) { s/(\d)(?=A? ALL)/$i/g; say }'
原回答
$ echo 'READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL' | perl -0777 -nE ' $_.="\n"; print;
while($i++<=3) { s/(\d)(?=A? ALL)/+1/ge; print } '
同时打印:
READ 1 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 1A ALL
READ 2 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 2A ALL
READ 3 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 3A ALL
READ 4 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 4A ALL
READ 5 ALL
DMN 2,3 ^DTND
DEL 2,3
WRITE 5A ALL