Chuyển sang cột chuyển đổi tập tin


15

Giả sử tôi có một tập tin:

Tệp1:

PAPER  TEAM  MANISH NISHA GARIMA JYOUTI ........etc 

File2 tôi muốn:

PAPER    
TEAM
MANISH
NISHA
GARIMA    
JYOUTI

Chuyển sang cột chuyển đổi của File1.


Nếu tệp của bạn chứa nhiều hơn một dòng và do đó đầu ra của bạn sẽ có nhiều hơn một cột, thì hãy thử tập lệnh AWK này .
Tạm dừng cho đến khi có thông báo mới.

Câu hỏi liên quan rất nhiều: Askubfox.com/q/461144/295286
Sergiy Kolodyazhnyy

Câu trả lời:


20

Sử dụng tr, thay thế từng ký tự không gian lặp lại ( ) bằng một \nký tự dòng mới ( ).

tr -s ' '  '\n'< infile > outfile

Nhưng tôi nghĩ bạn muốn một cái gì đó như thế này?

1 2 3 4 1 a #
abcd -> 2 b $
# $ @% 3 c @
                4 d%

Với awkchúng tôi có thể làm:

awk '{ for (i=1; i<=NF; i++) RtoC[i]= (RtoC[i]? RtoC[i] FS $i: $i) } 
    END{ for (i in RtoC) print RtoC[i] }' infile

Điều này kết hợp từng số được đặt cùng nhau vào vị trí và ENDin ra kết quả sẽ là hàng đầu tiên trong cột đầu tiên, hàng thứ hai trong cột thứ hai, v.v ... Tất nhiên tệp đầu vào được giới hạn ở kích thước bộ nhớ của bạn.


Tôi đã thử với cùng dữ liệu và mã, nó đã in cột cuối cùng dưới dạng bản ghi đầu tiên như 4 d% và sau đó là bản ghi thứ 2 1 a #, v.v.
Abhinay

8

Bạn chỉ có thể làm điều này thông qua grep. Theo mặc định grep, sẽ in trận đấu theo một dòng mới riêng biệt.

grep -oP '\S+' infile > outfile

HOẶC LÀ

grep -o '[^[:space:]]\+' infile > outfile

1
+1 để sử dụng sáng tạogrep
Volker Siegel

8

Bạn cũng có thể sử dụng fmtlệnh:

~$ cat f
PAPER  TEAM  MANISH NISHA GARIMA JYOUTI
~$ fmt -1 f
PAPER
TEAM
MANISH
NISHA
GARIMA
JYOUTI

7

Với dữ liệu GNU :

$ datamash -W transpose <file
PAPER
TEAM
MANISH
NISHA
GARIMA
JYOUTI

datamashcó vẻ như là công cụ tốt nhất cho nhiệm vụ, nhưng thật thú vị khi có bao nhiêu công cụ khác có thể được sử dụng!
Mark Stewart

6

Bạn cũng có thể làm điều này bằng cách sử dụng sed:

$ sed -e 's/  */\n/g' file1 > file2

LƯU Ý: Không xử lý tình huống trong đó các từ chứa khoảng trắng.


5

Sử dụng awk, đặt dấu tách trường đầu ra ( OFS) làm dấu phân cách bản ghi (dòng) ( RS):

awk '{OFS=RS;$1=$1}1' file > file2

2

Sử dụng một forvòng lặp:

for val in `cat file1` ; do echo $val >> file2; done;

0

Bạn cũng có thể thử sử dụng sed

$ sed -i.bak s@' '@'\n'@g infile.txt

Xin lưu ý rằng tôi đang sử dụng @như một dấu phân tách cho hoạt động thay thế. Điều này cũng sẽ tạo ra một tập tin sao lưu. Trong trường hợp bạn không cần sao lưu, hãy xóa .bak

$ sed -i s@' '@'\n'@g infile.txt

0

Phiên bản Python:

python -c "import sys;lines=[l.replace(' ','\n') for l in sys.stdin.readlines()];print(''.join(lines))" < input.txt > output.txt

Điều này sử dụng <chuyển hướng vào stdin của python từ input.txtvà ghi vào output.txtsử dụng >chuyển hướng. Bản thân một lớp đọc trong tất cả các dòng từ stdinmột danh sách các chuỗi, trong đó tất cả các khoảng trắng được thay thế bằng các dòng mới và chúng tôi xây dựng lại toàn bộ văn bản bằng .join()hàm.

Cách tiếp cận khác để tránh nhiều khoảng trống trong chuỗi được thay thế bằng dòng mới là sử dụng .split()để chia dòng thành danh sách các từ. Bằng cách đó, chúng tôi có thể đảm bảo rằng mỗi từ chỉ được phân tách bằng một dòng mới

python -c "import sys;lines=['\n'.join(l.strip().split()) for l in sys.stdin.readlines()];print('\n'.join(lines))" < input.txt > output.txt

0

Sử dụng xargs, (bị đánh cắp từ câu trả lời của souravc ):

xargs -n 1 < File1 > File2

Hoặc nếu có bất kỳ định dạng lại nhỏ nào là cần thiết, hãy sử dụng các printfchuỗi định dạng như có thể cần thiết:

xargs printf '%s\n' < File1 > File2

0

Giải pháp của tôi sẽ là:

#!/bin/bash
cols=$(head -1 file.txt | wc -w)
for i in $(seq 1 $cols); do
cut -d ' ' -f$i file.txt | tr '\n' ' ' | sed s'/.$//'
echo
done

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.