多次重复文字

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