2016-08-21 2 views
1

데이터 패턴이 반복되는 텍스트가 있는데 grep은 계속해서 모든 일치 항목을 계속 유지합니다.bash grep -e를 루프에 배열

some text..... 
Text.... 
..... 
1 O1 111111 111111 111111 
2 O2 222211 222211 222211 
3 O3 643653 652346 757686 
some text..... 
1 O1 111122 111122 111122 
2 O2 222222 222222 222222 
3 O3 343653 652346 757683 
some text..... 
1 O1 111333 111333 111333 
2 O2 222333 222333 222333 
3 O3 343653 652346 757684 
. 
. 
. 

그리고 그 결과 내가 갖는 :

xuz1[1] = 111111 111111 111111 
    xuz2[1] = 222211 222211 222211 
    xuz3[1] = 643653 652346 757686 

    xuz1[2] = 111111 111111 111111 
    xuz2[2] = 222211 222211 222211 
    xuz3[2] = 643653 652346 757686   

...

이 같은 결과를 찾고 :

for ((count = 1; count !=17; count++)); do  # 17 times 
xuz1[count]=`grep -e "1 O1" $out_file | cut -c10-29`  
xuz2[count]=`grep -e "2 O2" $out_file | cut -c10-29` 
xuz3[count]=`grep -e "3 O3" $out_file | cut -c10-29` 

echo ${xuz1[count]} 
echo ${xuz2[count]} 
echo ${xuz3[count]} 
done 

데이터처럼 보이는

xuz1[1]=111111 111111 111111 
xuz2[1]=222211 222211 222211 
xuz3[1]=343653 652346 757683 

xuz1[2]=111122 111122 111122 
xuz2[2]=222222 222222 222222 
xuz3[2]=343653 652346 757684 

또한 "grep -m 1 -e"시도했습니다 어떤 방법으로 가야합니까?

지금은 한 줄로 끝났습니다
grep -A4 -e "1 O1"$ out_file | 컷 -c10-29

일부 텍스트 .... 거대한 텍스트 부분이 있습니다.

+2

즉각적인 문제는 [인용] (http://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-variable)이지만 파일을 한 번 통과해야하는 것처럼 보입니다. 대신 Awk와. – tripleee

+0

작은 샘플 데이터, 필요한 출력, 전류 출력 및 ... 헐떡 거림, 일부 코드의 경우 pluse-uno! 이것은 특정 문제 도메인의 쉘 스크립팅을위한 모델 Q입니다! 계속 게시하고 행운을 빌어 요! – shellter

+0

감사합니다. 시도해 보겠습니다. –

답변

2

단일 그렙 함께 작은 bash는 스크립트는

grep -E '^[0-9]+ +O[0-9]+ +.*'| 
while read idx oidx cols; do 
    if ((idx == 1)); then 
    let ++i 
    name=xuz$i 
    let j=1 
    fi 
    echo "$name[$j]=$cols" 
    let ++j 
done 
+0

Perl 없이는 다른 방법이 있습니까? 그들이 서버에 무엇을 가지고 있는지 모르겠다. bash로 유지하여 쉘 스크립트로 동작 할 수 있도록하고 싶다. –

+0

perl이 아니었다. bash와 이전의 솔루션은 grep -P를 사용했다. – pakistanprogrammerclub

+0

ok, 나중에 –

0

당신은 정말 당신이 원하는 것을 설명하지 않은만큼,하지만 난 이런 일을 생각한다. 정규식이 일치하지 않는 경우

awk '! /^[1-9][0-9]* O[0-9]/{ n++; m=0; if (NR>1) print ""; next } 
    { print "xuz" ++m "[" n "]=" substr($0, 10) }' "$out_file" 

, 우리는 우리가 "텍스트"조각 중 하나를 찾고 있습니다 가정이 새로운 기록을 시작하도록. n을 증가시키고 m을 재설정하십시오. 그렇지 않으면이 레코드에이 항목에 대한 출력을 인쇄하십시오.

some text이 두 줄 이상일 수있는 경우 사소한 변경이 필요하지만 적어도 적절한 방향으로 보내면 충분합니다.

매우 비효율적 일지 모르지만 순수 Bash에서도이 작업을 수행 할 수 있습니다. Bash while read 루프가 Awk보다 적어도 100 배 이상 느리고 코드는 덜 관용적이며 우아합니다. .

while read -r m x result; do 
    case $m::$x in 
    [1-9]::O[1-9]) 
     printf 'xuz%d[%d]=%s\n' $m $n "$result;; 
    *) 
     # If n is unset, don't print an empty line 
     printf '%s' "${n+$'\n'}" 
     let ((n++));; 
    esac 
done <"$out_file" 

나는 순수 배쉬 (Bash)에서 이것을하기위한 모든 요구 사항에 적극적으로 도전 할 것입니다. 그것이 숙제 인 경우 요구 사항은 비현실적이며 쉘 스크립트 작성자의 핵심 기술은 쉘의 한계와 Awk와 같은 일반적인 지원 도구의 장점을 이해하는 것입니다. Awk 언어는 쉘이있는 곳이라면 어디에서나 사용할 수 있습니다. 특히 Bash와 같은 무거운 쉘을 사용할 수 있습니다. (제한된 예를 들어, 임베디드 환경에서 대시와 같은 제한된 쉘이 더 의미가있다. 그 다음이 스크립트가 제대로 휴대용 만들기 위해 열심히해서는 안됩니다 불구하고 let 키워드는 사용할 수 없습니다 예.)

case 문 정규 표현식이 아닌 glob 패턴을 받아들이므로 여기서 패턴은 약간 덜 일반적입니다 (첫 번째 필드에서 하나의 양수를 허용).

+0

미안하지만 저는 BASH 명령만을 사용하고 있습니다. –

+0

그것은 매우 의심스러운 요구 사항이지만 지금 당장의 업데이트를보십시오. (불행히도, 내가 테스트 할 수있는 장소가 아니며, 사소한 오타 또는 문법 피가 준비되어 있어야합니다.) – tripleee

0

토론에 참여해 주셔서 감사합니다.

***이 /// 속도 업에서 데이터를 추출에 사용되는 약 400 배 **

파일, 2000 선 주위에 포함되어 연구 계산에서 데이터를 추출 할 내 아내를 돕기 위해 내 집 프로젝트, 필요한 데이터 블록은 처럼 보이며 파일에서 10-20 회 반복됩니다.

while IFS= read line 
do 
IFS=' ' read -r -a arr_line <<< "$line"                    
# break line of xyz into 3 numbers 
s1=$(echo "${arr_line[0]}" \* 0.529177249 | bc -l)               
# some math convertion 
s2=$(echo "${arr_line[1]}" \* 0.529177249 | bc -l) 
s3=$(echo "${arr_line[2]}" \* 0.529177249 | bc -l) 

#-------to array non sorted ------------ 
arr[$n]=${n}";"${from_file}";"${gd_}";"${frt[count_4s]}";"${n4}";"${s1}";"${s2}";"${s3}         
echo ${arr[n]} 
#-------------------------------------------- 
done <"$from_file_txt" 

종류 |

uiyououy COORDINATES 

NR ATOM CCCCC  X    Y    Z 

    1 O1  8.00 0.000000000 0.882236820 -0.789494235 
    2 O2  8.00 0.000000000 -1.218250722 -1.644061652 
    3 O3  8.00 0.000000000 1.218328524 0.400260050 
    4 O4  8.00 0.000000000 -0.882314622 2.033295837 

Text text text text 
tons of text 

나는 다음

grep -A4 --no-group-separator -e "1 O1" $from_file | cut -c23-64  
>xyz_temp.txt  
    # grep 4 lines at once to txt 
sed -i '/^[ \t]*$/d' xyz_temp.txt                      
    #del empty lines from xyz txt 

아래 표현을 사용하는 4 개 라인을 추출하는 것은 ('기원전 -l'를 연산에 사용한다) 번호에 문자열을 변환하는 것입니다 배열

IFS=$'\n' sorted=($(sort -t \; -k4 -k5 -g <<<"${arr[*]}"))      
# -t separator ';' -k column -g generic * to get new line output 
#-k4 -k5 sort by column 4 then5 
#printf "%s\n" "${sorted[*]}" 
unset IFS 

마지막 데이터보기 결과에 결합 할 부분은 출력이

============================== sorted ============================== 
;;;;;1; 
17;A-13_A1+.out;1.3;0.4;1;0;.221176355474853043;-.523049776514580244 
18;A-13_A1+.out;1.3;0.4;2;0;-.550350051428402955;-.734584881824005358 
19;A-13_A1+.out;1.3;0.4;3;0;.665269869069959489;.133910683627893251 
20;A-13_A1+.out;1.3;0.4;4;0;-.336096173116409577;1.123723974181515102 
;;;;;2; 
13;A-13_A1+.out;1.3;0.45;1;0;.279265277182782148;-.504490787956469897 
14;A-13_A1+.out;1.3;0.45;2;0;-.583907412327951988;-.759310392973448167 
15;A-13_A1+.out;1.3;0.45;3;0;.662538493711206290;.146829200993661293 
16;A-13_A1+.out;1.3;0.45;4;0;-.357896358566036450;1.116971979936256771 
;;;;;3; 
9;A-13_A1+.out;1.3;0.5;1;0;.339333719743262501;-.482029749553797105 
10;A-13_A1+.out;1.3;0.5;2;0;-.612395507070451545;-.788968880150283253 
11;A-13_A1+.out;1.3;0.5;3;0;.658674809217196345;.163289820251690233 
12;A-13_A1+.out;1.3;0.5;4;0;-.385613021360830052;1.107708808923212876 

==END===END===END== 

* 노트처럼 보이는

echo "$n" 
n2=1 
n42=1 
count_4s2=1 
i=0 
echo "============================== sorted ==============================" 
################### loop for empty 4s lines 

printf "%s" ";" ";" ";" ";" ";" "${count_4s2}" ";" 
printf "%s\n" 
printf "%s\n" "${sorted[i]}" 
while [ $i -lt $((n-2)) ] 
do 
i=$((i+1)) 
if [ "$n42" = "4" ]        # 1234 
then n42=0 
    count_4s2=$((count_4s2+1)) 
    printf "%s" ";" ";" ";" ";" ";" "${count_4s2}" ";" 
    printf "%s\n" 
fi 
#-------------------------------------------- 
n2=$((n2+1)) 
n42=$((n42+1)) 
printf "%s\n" "${sorted[i]}" 
done ############# while 
#00000000000000000000000000000000000000 
printf "%s\n" 
echo ==END===END===END== 

: 일부 코드는 여기

표시하지 않을 수 있습니다

다음 단계로 엑셀에 붙여 넣기하는 것입니다; 분리 기호.