`echo "${var}"` 출력 선행 공백

`echo "${var}"` 출력 선행 공백

누구든지 나를 도와줄 수 있나요? 많은 파일을 생성하려고 하는데 echo를 사용하여 파일에 쓰려고 하면 다음과 같이 공백과 작은따옴표가 추가됩니다.

' (here is the space)  file.tmp' 

'  file1.tmp'

'  file3.tmp' 

코드는 다음과 같습니다.


cat limpio.tmp | while read line; do
  srcip=$(echo $line | awk -F"," '{print $1}')
  destip=$(echo $line | awk -F"," '{print $2}')
  port=$(echo $line | awk -F"," '{print $NF}')
  echo "${srcip}" >> "$destip.tmp"
done

문제는 cat을 사용하여 내용을 반복하고 보려고 할 때 발생하지만 공백으로 인해 작동하지 않습니다.

매우 감사합니다

답변1

echo유틸리티는 공백을 삽입하지만 출력 시 인수 사이의 구분 기호로만 사용됩니다.

$ echo 1    2 3       4 'A B     C'
1 2 3 4 A B     C

B과 사이의 공백은 C동일한 매개변수의 일부이므로 유지됩니다 echo.

echo그럼 이건 아닌데끼워 넣다공백이 있지만 데이터에 이미 공백이 포함되어 있습니다.

나는 당신이 보는 작은따옴표가 ls시스템 출력의 일부라고 가정합니다(참조"ls"가 갑자기 공백을 작은따옴표로 묶는 이유는 무엇입니까?) 또는 쉘이 실행 중일 때 추적 출력의 일부일 수 있습니다 set -x(참조bash가 명령을 실행하기 전에 따옴표가 없는 실패한 경로 이름 확장에 작은따옴표를 추가하는 이유는 무엇입니까?). 즉, 실제로 파일 이름의 일부가 아니라 일부 도구가 이름을 렌더링하는 방식일 뿐입니다.

예를 들어 입력 내용이 다음과 같다고 가정해 보겠습니다.

174.18.418.83, 10.404.401.94, 53144
174.18.418.83, 10.404.401.94, 53144
174.18.418.83, 10.404.401.94, 53144

쉼표 구분 기호 뒤에 공백이 있음을 알 수 있습니다. 쉼표를 구분 기호로 사용하여 위 파일에서 두 번째 필드를 읽으면 필드 시작 부분에 공백이 유지되고 해당 데이터를 파일 이름으로 사용하면 파일 이름이 공백으로 시작됩니다.

(주의깊은 독자라면 문제의 코드가 인용 line되지 않은 변수를 사용한다는 것을 알 수 있을 것입니다. 이는 쉘이 변수 값을 공백으로 분할하여 , 및 와 echo같은 별도의 매개변수로 표시한다는 것을 의미합니다 .174.18.418.83,10.404.401.94,53144그건 진실이야어떤 의미에서는 echo제거해야 할 공백을 삽입하지만 데이터에 공백/탭이 없으면 이 작업을 수행하지 않습니다. 당신은 또한 볼 수 있습니다언제 큰따옴표가 필요합니까?)

해결 방법은 쉼표와 다음 공백 문자를 구분 기호로 사용하는 것입니다 awk.

awk -F ',[[:blank:]]*' '{ print $2 }'

이 표현식은 ,[[:blank:]]*쉼표 뒤에 공백 문자가 여러 개 나오는 것과 일치합니다. "공백" 문자는 공백 또는 탭 문자입니다. , *리터럴 공백이 있다는 것을 알고 있는 경우 이를 ("쉼표, 공백, 별표")로 변경할 수 있습니다.

이제 전화를 피하세요awk 입력 파일의 각 줄에 대한 시간을 입력합니다.

print의 명령문은 파일 이름 뒤에 파일 이름을 awk사용하여 셸에서 출력을 리디렉션하는 것과 거의 동일한 방식으로 "리디렉션"될 수 있습니다.>

사용하려는 파일 이름은 두 번째 필드에 .tmp추가된 이름입니다.

이는 질문의 전체 루프를 단일 명령으로 바꿀 수 있음을 의미합니다 awk.

awk -F ',[[:blank:]]*' '{ print $1 > ($2 ".tmp") }' limpio.tmp

표현식은 두 번째 필드의 내용을 추가한 결과 문자열로 평가됩니다 ($2 ".tmp")..tmp

>with를 사용하면 print출력 파일이 첫 번째 파일에서 생성되거나 잘리며(비워지고) 동일한 이름 뒤에 print만 새 줄이 추가됩니다 . 대신 을 print사용하는 경우 첫 번째 항목은 파일을 자르는 대신 파일에 추가됩니다.>>>print

여기에는 온전성 검사가 내장되어 있지 않으므로 두 번째 열에 입력한 내용에 따라 위의 내용으로 인해 쓰기 액세스 권한이 있는 시스템의 중요한 파일이 손상될 수 있습니다.

GNU를 사용한다면 awk, 이것이 당신이 해야 할 일입니다. 그러나 다른 파일을 사용 awk하고 많은 수의 파일을 작성해야 하는 경우 close()파일을 처리할 때 이러한 파일을 수동으로 호출해야 할 수도 있습니다. 그렇지 않으면 사용 가능한 파일 설명자가 부족해질 수 있습니다.

awk -F ',[[:blank:]]*' '{ fn = $2 ".tmp"; print $1 >>fn; close(fn) }' limpio.tmp

여기서는 출력 파일 이름을 변수에 저장합니다 fn. 그런 다음 출력을 파일에 추가한 다음 파일을 닫습니다. 이렇게 하면 사용 가능한 파일 설명자를 모두 사용하지 않아도 되지만 명령을 다시 실행해야 하는 경우 출력 파일을 항상 사용 >>하고 수동으로 정리(삭제)해야 합니다 .printawk

GNU는 awk열려 있는 파일 설명자의 수를 추적하고 필요할 때 닫기 시작합니다(나중에 파일에 더 많은 데이터를 써야 할 경우 추가하기 위해 파일을 다시 엽니다).

또한보십시오:

답변2

원래 게시한 코드는 다음과 같습니다.

cat limpio.tmp | while read line; do
  srcip=$(echo $line | awk -F"," '{print $1}')
  destip=$(echo $line | awk -F"," '{print $2}')
  port=$(echo $line | awk -F"," '{print $NF}')
  echo "${srcip}" >> "$destip.tmp"
done

이것은 불필요하게 복잡합니다. 쉼표로 구분된 필드를 읽는 것을 보면 해당 필드를 변수로 직접 읽을 수 있습니다.

while IFS=$' \t\n,' read -r srcip destip port junk ;do
  echo "$srcip" >> "${destip}.tmp"
done <limpio.tmp

답변3

가장 간단한 수정은 큰따옴표를 제거하는 것입니다 echo "${srcip}".

자신을 살펴보십시오:

var=' spacy '
echo X$(echo "$var")X
echo X$(echo $var)X

관련 정보