Vòng qua nội dung của một tệp trong Bash


1388

Làm cách nào để lặp lại qua từng dòng của tệp văn bản với Bash ?

Với kịch bản này:

echo "Start!"
for p in (peptides.txt)
do
    echo "${p}"
done

Tôi nhận được đầu ra này trên màn hình:

Start!
./runPep.sh: line 3: syntax error near unexpected token `('
./runPep.sh: line 3: `for p in (peptides.txt)'

(Sau này tôi muốn làm một cái gì đó phức tạp $phơn là chỉ xuất ra màn hình.)


Biến môi trường SHELL là (từ env):

SHELL=/bin/bash

/bin/bash --version đầu ra:

GNU bash, version 3.1.17(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

cat /proc/version đầu ra:

Linux version 2.6.18.2-34-default (geeko@buildhost) (gcc version 4.1.2 20061115 (prerelease) (SUSE Linux)) #1 SMP Mon Nov 27 11:46:27 UTC 2006

Tệp peptides.txt chứa:

RKEKNVQ
IPKKLLQK
QYFHQLEKMNVK
IPKKLLQK
GDLSTALEVAIDCYEK
QYFHQLEKMNVKIPENIYR
RKEKNVQ
VLAKHGKLQDAIN
ILGFMK
LEDVALQILL

19
Ồ, tôi thấy nhiều điều đã xảy ra ở đây: tất cả các bình luận đã bị xóa và câu hỏi được mở lại. Chỉ để tham khảo, câu trả lời được chấp nhận trong Đọc một dòng tệp bằng cách gán giá trị cho một biến giải quyết vấn đề theo cách chính tắc và nên được ưu tiên hơn dòng được chấp nhận ở đây.
fedorqui 'SO ngừng làm hại'

Câu trả lời:


2096

Một cách để làm điều đó là:

while read p; do
  echo "$p"
done <peptides.txt

Như đã chỉ ra trong các bình luận, điều này có tác dụng phụ trong việc cắt xén khoảng trắng hàng đầu, diễn giải các chuỗi dấu gạch chéo ngược và bỏ qua dòng cuối cùng nếu nó thiếu một nguồn cấp dữ liệu kết thúc. Nếu đây là những lo ngại, bạn có thể làm:

while IFS="" read -r p || [ -n "$p" ]
do
  printf '%s\n' "$p"
done < peptides.txt

Ngoại lệ, nếu thân vòng lặp có thể đọc từ đầu vào tiêu chuẩn , bạn có thể mở tệp bằng một mô tả tệp khác:

while read -u 10 p; do
  ...
done 10<peptides.txt

Ở đây, 10 chỉ là một số tùy ý (khác với 0, 1, 2).


7
Làm thế nào tôi nên giải thích dòng cuối cùng? Tệp peptides.txt được chuyển hướng đến đầu vào tiêu chuẩn và bằng cách nào đó cho toàn bộ khối while?
Peter Mortensen

11
"Slurp peptides.txt vào vòng lặp while này, vì vậy lệnh 'đọc' có thứ gì đó để tiêu thụ." Phương thức "con mèo" của tôi cũng tương tự, gửi đầu ra của lệnh vào khối while để tiêu thụ bằng cách 'đọc', chỉ có điều nó khởi chạy một chương trình khác để hoàn thành công việc.
Warren Young

8
Phương pháp này dường như bỏ qua dòng cuối cùng của một tập tin.
xastor

5
Nhân đôi lời thoại !! echo "$ p" và tập tin .. tin tôi đi, nó sẽ cắn bạn nếu bạn không !!! TÔI BIẾT! lol
Mike Q

5
Cả hai phiên bản không đọc được dòng cuối cùng nếu nó không được kết thúc bằng một dòng mới. Luôn luôn sử dụngwhile read p || [[ -n $p ]]; do ...
dawg

448
cat peptides.txt | while read line 
do
   # do something with $line here
done

và biến thể một lớp lót:

cat peptides.txt | while read line; do something_with_$line_here; done

Các tùy chọn này sẽ bỏ qua dòng cuối cùng của tệp nếu không có nguồn cấp dữ liệu dòng.

Bạn có thể tránh điều này bằng cách sau:

cat peptides.txt | while read line || [[ -n $line ]];
do
   # do something with $line here
done

68
Nói chung, nếu bạn đang sử dụng "con mèo" chỉ với một đối số, bạn đang làm gì đó sai (hoặc không tối ưu).
JesperE

27
Vâng, nó không hiệu quả như của Bruno, vì nó khởi chạy một chương trình khác, không cần thiết. Nếu vấn đề hiệu quả, hãy làm theo cách của Bruno. Tôi nhớ theo cách của tôi vì bạn có thể sử dụng nó với các lệnh khác, trong đó cú pháp "redirect in from" không hoạt động.
Warren Young

74
Có một vấn đề khác nghiêm trọng hơn với vấn đề này: bởi vì vòng lặp while là một phần của đường ống, nó chạy trong một mạng con và do đó, bất kỳ biến nào được đặt bên trong vòng lặp đều bị mất khi thoát ra (xem bash-hackers.org/wiki/doku. php / phản chiếu / bashfaq / 024 ). Điều này có thể rất khó chịu (tùy thuộc vào những gì bạn đang cố gắng thực hiện trong vòng lặp).
Gordon Davisson

25
Tôi sử dụng "tập tin mèo |" là khởi đầu của rất nhiều lệnh của tôi hoàn toàn vì tôi thường tạo nguyên mẫu với "tập tin đầu |"
mat kelcey

62
Điều này có thể không hiệu quả, nhưng nó dễ đọc hơn nhiều so với các câu trả lời khác.
Người đọc man rợ

144

Tùy chọn 1a: Vòng lặp while: Dòng đơn tại một thời điểm: Chuyển hướng đầu vào

#!/bin/bash
filename='peptides.txt'
echo Start
while read p; do 
    echo $p
done < $filename

Tùy chọn 1b: Vòng lặp while: Dòng đơn tại một thời điểm:
Mở tệp, đọc từ bộ mô tả tệp (trong trường hợp này là bộ mô tả tệp số 4).

#!/bin/bash
filename='peptides.txt'
exec 4<$filename
echo Start
while read -u4 p ; do
    echo $p
done

Đối với tùy chọn 1b: bộ mô tả tệp có cần phải đóng lại không? Ví dụ: vòng lặp có thể là một vòng lặp bên trong.
Peter Mortensen

3
Bộ mô tả tập tin sẽ được dọn sạch với các lối thoát quy trình. Một đóng rõ ràng có thể được thực hiện để sử dụng lại số fd. Để đóng fd, hãy sử dụng một exec khác với cú pháp & -, như thế này: exec 4 <& -
Stan Graves

1
Cảm ơn bạn vì Lựa chọn 2. Tôi gặp phải vấn đề lớn với Lựa chọn 1 vì tôi cần đọc từ stdin trong vòng lặp; trong trường hợp như vậy, Phương án 1 sẽ không hoạt động.
masgo

4
Bạn nên chỉ ra rõ ràng hơn rằng Phương án 2 không được khuyến khích . @masgo Tùy chọn 1b sẽ hoạt động trong trường hợp đó và có thể được kết hợp với cú pháp chuyển hướng đầu vào từ Tùy chọn 1a bằng cách thay thế done < $filenamebằng done 4<$filename(rất hữu ích nếu bạn muốn đọc tên tệp từ một tham số lệnh, trong trường hợp đó bạn chỉ có thể thay thế $filenamebằng $1).
Egor Hans

Tôi cần lặp lại nội dung tập tin, chẳng hạn như tail -n +2 myfile.txt | grep 'somepattern' | cut -f3trong khi chạy các lệnh ssh bên trong vòng lặp (tiêu thụ stdin); Tùy chọn 2 ở đây dường như là cách duy nhất?
dùng5359531

85

Điều này không tốt hơn các câu trả lời khác, nhưng là một cách nữa để hoàn thành công việc trong một tệp không có khoảng trắng (xem bình luận). Tôi thấy rằng tôi thường cần một lớp lót để tìm hiểu danh sách trong các tệp văn bản mà không cần thêm bước sử dụng các tệp script riêng biệt.

for word in $(cat peptides.txt); do echo $word; done

Định dạng này cho phép tôi đặt tất cả trong một dòng lệnh. Thay đổi phần "echo $ word" thành bất cứ điều gì bạn muốn và bạn có thể đưa ra nhiều lệnh được phân tách bằng dấu chấm phẩy. Ví dụ sau sử dụng nội dung của tệp làm đối số thành hai tập lệnh khác mà bạn có thể đã viết.

for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done

Hoặc nếu bạn có ý định sử dụng cái này như một trình soạn thảo luồng (tìm hiểu sed), bạn có thể chuyển đầu ra sang một tệp khác như sau.

for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done > outfile.txt

Tôi đã sử dụng chúng như được viết ở trên vì tôi đã sử dụng các tệp văn bản nơi tôi đã tạo chúng với một từ trên mỗi dòng. (Xem bình luận) Nếu bạn có khoảng trắng mà bạn không muốn chia từ / dòng của mình, nó sẽ xấu hơn một chút, nhưng lệnh tương tự vẫn hoạt động như sau:

OLDIFS=$IFS; IFS=$'\n'; for line in $(cat peptides.txt); do cmd_a.sh $line; cmd_b.py $line; done > outfile.txt; IFS=$OLDIFS

Điều này chỉ bảo shell chỉ phân chia trên các dòng mới, không phải khoảng trắng, sau đó trả lại môi trường trở lại như trước đây. Tại thời điểm này, bạn có thể muốn xem xét đưa tất cả vào một tập lệnh shell thay vì ép tất cả vào một dòng duy nhất.

May mắn nhất!


6
Bash $ (<peptides.txt) có lẽ thanh lịch hơn, nhưng vẫn sai, điều Joao nói chính xác, bạn đang thực hiện logic thay thế lệnh trong đó không gian hoặc dòng mới là cùng một thứ. Nếu một dòng có khoảng trắng trong đó, vòng lặp sẽ thực thi TWICE trở lên cho một dòng đó. Vì vậy, mã của bạn nên đọc đúng: cho từ trong $ (<peptides.txt); làm .... Nếu bạn biết thực tế không có khoảng trắng, thì một dòng bằng một từ và bạn ổn.
maxpolk

2
@ JoaoCosta, maxpolk: Những điểm tốt mà tôi chưa xem xét. Tôi đã chỉnh sửa bài viết gốc để phản ánh chúng. Cảm ơn!
mightypile 22/12/13

2
Việc sử dụng forlàm cho các mã thông báo / dòng đầu vào có thể mở rộng hệ vỏ, thường không mong muốn; hãy thử điều này: for l in $(echo '* b c'); do echo "[$l]"; done- như bạn sẽ thấy, *- mặc dù ban đầu là một chữ được trích dẫn - mở rộng ra các tệp trong thư mục hiện tại.
mkuity0

2
@dblanchard: Ví dụ cuối cùng, sử dụng $ IFS, nên bỏ qua khoảng trắng. Bạn đã thử phiên bản đó chưa?
mightypile

4
Cách thức lệnh này trở nên phức tạp hơn rất nhiều vì các vấn đề quan trọng đã được khắc phục, trình bày rất rõ lý do tại sao sử dụng forđể lặp lại các dòng tệp là một ý tưởng tồi. Thêm vào đó, khía cạnh mở rộng được đề cập bởi @ mkuity0 (mặc dù điều đó có thể bị phá vỡ bằng cách đưa vào các trích dẫn thoát, điều này một lần nữa làm cho mọi thứ phức tạp hơn và khó đọc hơn).
Egor Hans

69

Một vài điều nữa không được bao gồm bởi các câu trả lời khác:

Đọc từ một tệp phân cách

# ':' is the delimiter here, and there are three fields on each line in the file
# IFS set below is restricted to the context of `read`, it doesn't affect any other code
while IFS=: read -r field1 field2 field3; do
  # process the fields
  # if the line has less than three fields, the missing fields will be set to an empty string
  # if the line has more than three fields, `field3` will get all the values, including the third field plus the delimiter(s)
done < input.txt

Đọc từ đầu ra của lệnh khác, sử dụng thay thế quá trình

while read -r line; do
  # process the line
done < <(command ...)

Cách tiếp cận này tốt hơn command ... | while read -r line; do ...bởi vì vòng lặp while ở đây chạy trong trình bao hiện tại chứ không phải là một lớp con như trong trường hợp sau. Xem bài liên quan Một biến được sửa đổi trong vòng lặp while không được ghi nhớ .

Đọc từ một đầu vào phân cách null, ví dụ find ... -print0

while read -r -d '' line; do
  # logic
  # use a second 'read ... <<< "$line"' if we need to tokenize the line
done < <(find /path/to/dir -print0)

Đọc liên quan: BashFAQ / 020 - Làm cách nào tôi có thể tìm và xử lý an toàn tên tệp chứa dòng mới, dấu cách hoặc cả hai?

Đọc từ nhiều tệp cùng một lúc

while read -u 3 -r line1 && read -u 4 -r line2; do
  # process the lines
  # note that the loop will end when we reach EOF on either of the files, because of the `&&`
done 3< input1.txt 4< input2.txt

Dựa trên câu trả lời của @ chepner tại đây :

-ulà một phần mở rộng bash. Để tương thích POSIX, mỗi cuộc gọi sẽ trông giống như vậy read -r X <&3.

Đọc toàn bộ tệp thành một mảng (phiên bản Bash trước đó đến 4)

while read -r line; do
    my_array+=("$line")
done < my_file

Nếu tệp kết thúc bằng một dòng không đầy đủ (dòng mới bị thiếu ở cuối), thì:

while read -r line || [[ $line ]]; do
    my_array+=("$line")
done < my_file

Đọc toàn bộ tệp thành một mảng (Bash phiên bản 4x trở lên)

readarray -t my_array < my_file

hoặc là

mapfile -t my_array < my_file

Và sau đó

for line in "${my_array[@]}"; do
  # process the lines
done

Bài viết liên quan:


lưu ý rằng thay vì command < input_filename.txtbạn luôn có thể làm input_generating_command | commandhoặccommand < <(input_generating_command)
masterxilo

1
Cảm ơn đã đọc tập tin thành mảng. Chính xác những gì tôi cần, bởi vì tôi cần mỗi dòng để phân tích hai lần, thêm vào các biến mới, thực hiện một số xác nhận, v.v.
frank_108

45

Sử dụng một vòng lặp while, như thế này:

while IFS= read -r line; do
   echo "$line"
done <file

Ghi chú:

  1. Nếu bạn không đặt IFSđúng, bạn sẽ mất thụt lề.

  2. Bạn hầu như luôn luôn nên sử dụng tùy chọn -r với đọc.

  3. Đừng đọc những dòng với for


2
Tại sao lại -rchọn?
David C. Rankin

2
@ DavidC.Rankin Tùy chọn -r ngăn chặn giải thích dấu gạch chéo ngược. Note #2là một liên kết nơi nó được mô tả chi tiết ...
Jahid

Kết hợp điều này với tùy chọn "đọc -u" trong câu trả lời khác và sau đó thật hoàn hảo.
Florin Andrei

@FlorinAndrei: Ví dụ trên không cần -utùy chọn, bạn đang nói về một ví dụ khác với -u?
Jahid

Đã xem qua các liên kết của bạn và rất ngạc nhiên không có câu trả lời nào chỉ đơn giản là liên kết liên kết của bạn trong Note 2. Trang đó cung cấp mọi thứ bạn cần biết về chủ đề đó. Hoặc là câu trả lời chỉ liên kết được khuyến khích hoặc một cái gì đó?
Egor Hans

14

Giả sử bạn có tệp này:

$ cat /tmp/test.txt
Line 1
    Line 2 has leading space
Line 3 followed by blank line

Line 5 (follows a blank line) and has trailing space    
Line 6 has no ending CR

Có bốn yếu tố sẽ thay đổi ý nghĩa của đầu ra tệp được đọc bởi nhiều giải pháp Bash:

  1. Dòng trống 4;
  2. Không gian hàng đầu hoặc dấu trên hai dòng;
  3. Duy trì ý nghĩa của các dòng riêng lẻ (nghĩa là mỗi dòng là một bản ghi);
  4. Dòng 6 không được kết thúc bằng CR.

Nếu bạn muốn dòng tệp văn bản theo dòng bao gồm dòng trống và dòng kết thúc không có CR, bạn phải sử dụng vòng lặp while và bạn phải có một bài kiểm tra thay thế cho dòng cuối cùng.

Dưới đây là các phương pháp có thể thay đổi tệp (so với những gì cattrả về):

1) Mất dòng cuối cùng và khoảng trắng ở đầu và cuối:

$ while read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'

(Nếu bạn while IFS= read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txtthay vào đó, bạn giữ nguyên các khoảng trắng ở đầu và cuối nhưng vẫn mất dòng cuối cùng nếu nó không bị chấm dứt với CR)

2) Sử dụng thay thế quá trình với catsẽ đọc toàn bộ tệp trong một ngụm và mất ý nghĩa của các dòng riêng lẻ:

$ for p in "$(cat /tmp/test.txt)"; do printf "%s\n" "'$p'"; done
'Line 1
    Line 2 has leading space
Line 3 followed by blank line

Line 5 (follows a blank line) and has trailing space    
Line 6 has no ending CR'

(Nếu bạn xóa "từ $(cat /tmp/test.txt)bạn đọc tệp từng chữ chứ không phải một ngụm. Cũng có thể không phải là những gì được dự định ...)


Cách mạnh mẽ và đơn giản nhất để đọc từng dòng tệp và giữ tất cả khoảng cách là:

$ while IFS= read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
'    Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space    '
'Line 6 has no ending CR'

Nếu bạn muốn loại bỏ không gian hàng đầu và giao dịch, hãy xóa IFS=phần:

$ while read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
'Line 6 has no ending CR'

(Một tệp văn bản không có dấu chấm dứt \n, trong khi khá phổ biến, được coi là bị hỏng trong POSIX. Nếu bạn có thể tin tưởng vào dấu vết \nbạn không cần || [[ -n $line ]]trong whilevòng lặp.)

Thông tin khác tại Câu hỏi thường gặp về BASH


13

Nếu bạn không muốn đọc của bạn bị phá vỡ bởi ký tự dòng mới, hãy sử dụng -

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
    echo "$line"
done < "$1"

Sau đó chạy tập lệnh với tên tệp làm tham số.


4
#!/bin/bash
#
# Change the file name from "test" to desired input file 
# (The comments in bash are prefixed with #'s)
for x in $(cat test.txt)
do
    echo $x
done

7
Câu trả lời này cần những lời cảnh báo được đề cập trong câu trả lời của mightypile và nó có thể thất bại nặng nề nếu bất kỳ dòng nào chứa ký tự đại diện hệ vỏ (do "$ x" không được trích dẫn).
Toby Speight

7
Tôi thực sự ngạc nhiên khi mọi người chưa nghĩ ra những dòng thông thường Đừng đọc với ...
Egor Hans

3

Dưới đây là ví dụ thực tế của tôi về cách lặp các dòng của đầu ra chương trình khác, kiểm tra các chuỗi con, bỏ dấu ngoặc kép từ biến, sử dụng biến đó bên ngoài vòng lặp. Tôi đoán khá nhiều người đang hỏi những câu hỏi này sớm hay muộn.

##Parse FPS from first video stream, drop quotes from fps variable
## streams.stream.0.codec_type="video"
## streams.stream.0.r_frame_rate="24000/1001"
## streams.stream.0.avg_frame_rate="24000/1001"
FPS=unknown
while read -r line; do
  if [[ $FPS == "unknown" ]] && [[ $line == *".codec_type=\"video\""* ]]; then
    echo ParseFPS $line
    FPS=parse
  fi
  if [[ $FPS == "parse" ]] && [[ $line == *".r_frame_rate="* ]]; then
    echo ParseFPS $line
    FPS=${line##*=}
    FPS="${FPS%\"}"
    FPS="${FPS#\"}"
  fi
done <<< "$(ffprobe -v quiet -print_format flat -show_format -show_streams -i "$input")"
if [ "$FPS" == "unknown" ] || [ "$FPS" == "parse" ]; then 
  echo ParseFPS Unknown frame rate
fi
echo Found $FPS

Khai báo biến bên ngoài vòng lặp, đặt giá trị và sử dụng nó bên ngoài vòng lặp yêu cầu thực hiện cú pháp <<< "$ (...)" . Ứng dụng cần phải được chạy trong một bối cảnh của giao diện điều khiển hiện tại. Báo giá xung quanh lệnh giữ dòng mới của luồng đầu ra.

Kết hợp vòng lặp cho chuỗi con sau đó đọc name = cặp giá trị , tách phần bên phải của last = character, bỏ trích dẫn đầu tiên, giảm trích dẫn cuối cùng, chúng ta có một giá trị sạch sẽ được sử dụng ở nơi khác.


3
Trong khi câu trả lời là chính xác, tôi không hiểu làm thế nào nó kết thúc ở đây. Phương pháp thiết yếu giống như đề xuất của nhiều câu trả lời khác. Thêm vào đó, nó hoàn toàn chìm đắm trong ví dụ FPS của bạn.
Egor Hans

0

Điều này đến khá muộn, nhưng với suy nghĩ rằng nó có thể giúp được ai đó, tôi đang thêm câu trả lời. Ngoài ra đây có thể không phải là cách tốt nhất. headlệnh có thể được sử dụng với -nđối số để đọc n dòng từ đầu tệp và tương tự taillệnh có thể được sử dụng để đọc từ dưới lên. Bây giờ, để tìm nạp dòng thứ n từ tệp, chúng tôi đứng đầu n dòng , dẫn dữ liệu đến đuôi chỉ 1 dòng từ dữ liệu đường ống.

   TOTAL_LINES=`wc -l $USER_FILE | cut -d " " -f1 `
   echo $TOTAL_LINES       # To validate total lines in the file

   for (( i=1 ; i <= $TOTAL_LINES; i++ ))
   do
      LINE=`head -n$i $USER_FILE | tail -n1`
      echo $LINE
   done

1
Đừng làm điều này. Việc lặp lại các số dòng và tìm nạp từng dòng riêng lẻ bằng cách sedhoặc head+ tailkhông hiệu quả, và tất nhiên đặt ra câu hỏi tại sao bạn không đơn giản sử dụng một trong những giải pháp khác ở đây. Nếu bạn cần biết số dòng, thêm bộ đếm vào while read -rvòng lặp của bạn hoặc sử dụng nl -bađể thêm tiền tố số dòng cho mỗi dòng trước vòng lặp.
tripleee

-1

@Peter: Điều này có thể giúp ích cho bạn-

echo "Start!";for p in $(cat ./pep); do
echo $p
done

Điều này sẽ trả lại đầu ra-

Start!
RKEKNVQ
IPKKLLQK
QYFHQLEKMNVK
IPKKLLQK
GDLSTALEVAIDCYEK
QYFHQLEKMNVKIPENIYR
RKEKNVQ
VLAKHGKLQDAIN
ILGFMK
LEDVALQILL


3
Câu trả lời này đang đánh bại tất cả các nguyên tắc được đặt ra bởi các câu trả lời tốt ở trên!
tiền mã hóa

3
Hãy xóa câu trả lời này.
dawg

3
Bây giờ các bạn, đừng phóng đại. Câu trả lời là xấu, nhưng nó dường như hoạt động, ít nhất là cho các trường hợp sử dụng đơn giản. Miễn là điều đó được cung cấp, là một câu trả lời tồi không lấy đi quyền tồn tại của câu trả lời.
Egor Hans

3
@EgorHans, tôi không đồng ý mạnh mẽ: Quan điểm của câu trả lời là dạy mọi người cách viết phần mềm. Dạy mọi người làm mọi thứ theo cách mà bạn biết là có hại cho họ và những người sử dụng phần mềm của họ (giới thiệu lỗi / hành vi bất ngờ / v.v.) đang cố ý làm hại người khác. Một câu trả lời được biết là có hại không có "quyền tồn tại" trong tài nguyên giảng dạy được quản lý chặt chẽ (và quản lý nó chính xác là những gì chúng ta, những người đang bỏ phiếu và gắn cờ, được cho là đang làm ở đây).
Charles Duffy
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.