두 개의 변수를 사용하여 단일 텍스트 파일을 구성합니다.

두 개의 변수를 사용하여 단일 텍스트 파일을 구성합니다.

다음 내용으로 텍스트 파일을 만들려고 합니다.

user name is ${name}
and his mobile number is ${number}

사용자가 10명이고 휴대폰 번호가 10개 있습니다. 사용자 이름은 에 저장 user.txt되고 연락처 번호는 에 저장됩니다 contact.txt.

user.txt다음과 같습니다.

apple
cat
tom

contact.txt다음과 같이,

1234
3456
5678

내 출력은 다음과 같습니다.

user name is apple
and his mobile number is 1234

user name is cat
and his mobile number is 3456

user name is tom
and his mobile number is 5678

이 출력을 단일 파일로 원합니다. 누군가 쉘 및 Python 스크립트를 도와줄 수 있습니까?

답변1

이는 표준 셸 내장 및 일반 도구를 사용하여 수행할 수 있습니다.

paste -d'|' user.txt contact.txt | while IFS='|' read user contact ; do
  printf "user name is %s\nand their mobile is %s\n" "${user}" "${contact}"
done

입력 리디렉션에 종종 선호되는 bashism을 사용한 약간의 리믹스입니다.

while IFS='|' read user contact ; do
  printf "user name is %s\nand their mobile is %s\n" "${user}" "${contact}"
done < <(paste -d"|" user.txt contact.txt)

> "somefilename.txt"명령의 마지막 줄에 추가하면 전체 출력을 선택한 파일로 리디렉션할 수 있습니다.

답변2

paste명령을 사용하면 두 파일의 행을 쌍으로 연결하여 더 쉽게 읽을 수 있습니다.

paste user.txt contact.txt

그러면 두 개의 필드로 구성된 탭으로 구분된 데이터 스트림이 생성됩니다.

이는 읽고 수정하기 쉽습니다 awk. 예를 들면 다음과 같습니다.

awk -F '\t' '{ printf "user name is %s\nand his mobile number is %s\n\n", $1, $2 }'

이는 출력 문자열을 printf생성 하는 데 사용됩니다 . awk의 출력에서 ​​읽은 두 필드는 paste자동으로 읽어 $1$2출력 문자열의 표시된 위치에 삽입됩니다 %s( 에 인수로 제공되는 다음 문자열에 대한 자리 표시자 printf). -F '\t'명령줄에서 awk필드 구분 기호를 탭으로 설정합니다 .

이 두 가지를 함께 놓고 테스트해 보세요.

$ paste user.txt contact.txt | awk -F '\t' '{ printf "user name is %s\nand his mobile number is %s\n\n", $1, $2 }'
user name is apple
and his mobile number is 1234

user name is cat
and his mobile number is 3456

user name is tom
and his mobile number is 5678

>somename명령 끝에 사용하여 파일로 리디렉션합니다.


또 다른 접근 방식은 첫 번째와 두 번째 필드 대신 출력 필드 구분 기호( OFS)와 출력 레코드 구분 기호( )를 수정하는 것입니다( 끝의 후행으로 인해 수정된 줄이 출력됩니다).ORSprintf1

paste user.txt contact.txt |
awk -F '\t' -v OFS='\n' -v ORS='\n\n' '{ $1 = "user name is " $1; $2 = "and his mobile number is " $2 }; 1'

답변3

bashmapfile파일을 한 줄에 하나의 요소로 배열로 읽는 내장 명령이 있습니다 . -t후행 줄 바꿈을 제거하십시오. 그런 다음 배열을 반복할 수 있습니다.

#!/bin/bash
mapfile -t user <user.txt
mapfile -t number <contact.txt
for (( i=0 ; i<${#user[@]} ; i++ )) ; do
  echo "user name is ${user[i]}"
  echo "and his mobile number is ${number[i]}"
  echo
done

답변4

그리고 zsh:

users=( ${(f)"$(<users.txt)"} )
numbers=( ${(f)"$(<numbers.txt)"} )
printf 'user name is %s\nand their mobile is %s\n\n' ${users:^numbers}

${A:^B}${A:^^B}두 개의 배열 압축 연산자입니다 . 두 배열의 길이가 다른 경우 둘 사이의 차이를 볼 수 있습니다. A=(a b c) B=(1 2 3 4 5)이 경우 에는 ${A:^B}Yield a 1 b 2 c 3(일치에서 초과분 삭제 B)와 ${A:^^B}Yield a 1 b 2 c 3 a 4 b 5( A초과분 일치를 위해 멤버 재사용) 가 있습니다 B.

관련 정보