string
? wstring
? std::string
basic_string
шаблонные на char
, и std::wstring
на wchar_t
.
char
по сравнению с [1 110] char
, как предполагается, содержит символ, обычно 8-разрядный символ. wchar_t
, как предполагается, содержит широкий символ, и затем, вещи становятся хитрыми:
На Linux, wchar_t
4 байта, в то время как в Windows, это - 2 байта.
проблема состоит в том, что ни char
, ни wchar_t
непосредственно связывается с unicode.
Позволяют нам взять ОС Linux: Моя система Ubuntu уже unicode знающая. Когда я работаю с символьной строкой, она исходно кодируется в [1 150] UTF-8 (т.е. строка Unicode символов). Следующий код:
#include
#include
int main(int argc, char* argv[])
{
const char text[] = "olé" ;
std::cout << "sizeof(char) : " << sizeof(char) << std::endl ;
std::cout << "text : " << text << std::endl ;
std::cout << "sizeof(text) : " << sizeof(text) << std::endl ;
std::cout << "strlen(text) : " << strlen(text) << std::endl ;
std::cout << "text(ordinals) :" ;
for(size_t i = 0, iMax = strlen(text); i < iMax; ++i)
{
std::cout << " " << static_cast(
static_cast(text[i])
);
}
std::cout << std::endl << std::endl ;
// - - -
const wchar_t wtext[] = L"olé" ;
std::cout << "sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl ;
//std::cout << "wtext : " << wtext << std::endl ; <- error
std::cout << "wtext : UNABLE TO CONVERT NATIVELY." << std::endl ;
std::wcout << L"wtext : " << wtext << std::endl;
std::cout << "sizeof(wtext) : " << sizeof(wtext) << std::endl ;
std::cout << "wcslen(wtext) : " << wcslen(wtext) << std::endl ;
std::cout << "wtext(ordinals) :" ;
for(size_t i = 0, iMax = wcslen(wtext); i < iMax; ++i)
{
std::cout << " " << static_cast(
static_cast(wtext[i])
);
}
std::cout << std::endl << std::endl ;
return 0;
}
выводы следующий текст:
sizeof(char) : 1
text : olé
sizeof(text) : 5
strlen(text) : 4
text(ordinals) : 111 108 195 169
sizeof(wchar_t) : 4
wtext : UNABLE TO CONVERT NATIVELY.
wtext : ol�
sizeof(wtext) : 16
wcslen(wtext) : 3
wtext(ordinals) : 111 108 233
Вы будете видеть, что "olГ©" текст в [1 116] действительно создается четырьмя символами: 110, 108, 195 и 169 (не подсчет конечного нуля). (Я позволю Вам учиться эти wchar_t
код как осуществление)
Так, при работе с char
на Linux, необходимо обычно заканчивать тем, что использовали Unicode, даже не зная это. И как [1 119] работы с [1 120], таким образом std::string
уже unicode-готово.
Примечание, что std::string
, как API струны до, будет полагать, что строка "olГ©" имеет 4 символа, не три. Таким образом, необходимо быть осторожными при усечении/игре с unicode символами, потому что некоторая комбинация символов запрещается в UTF-8.
В Windows, это несколько отличается. Win32 должен был поддержать много приложения, работающего с [1 123] и на различном наборы символов / кодовые страницы произведенный во всем мире перед появлением Unicode.
, Таким образом, их решением было интересное: Если приложение работает с [1 124], то символьные строки закодированы/распечатаны/показаны на маркировках GUI с помощью локального набора символов/кодовой страницы на машине. Например, "olГ©" был бы "olГ©" в локализованном французами Windows, но будет чем-то другим в локализованном кириллицей Windows ("olР№", если Вы используете Windows 1251 ). Таким образом, "исторические приложения" будут обычно все еще работать тот же старый путь.
Для основанных на Unicode приложений, использование Windows wchar_t
, который 2 байта шириной, и кодируется в [1 154] UTF-16, который является Unicode, закодированным на 2-байтовых символах (или по крайней мере, главным образом совместимый UCS-2, который является почти тем же самым IIRC).
Приложения с помощью [1 126] сказаны "многобайтовые" (потому что каждый глиф состоит из одного или нескольких char
с, в то время как приложения с помощью [1 128] сказаны "widechar" (потому что каждый глиф состоит из один или два wchar_t
. См. MultiByteToWideChar и API WideCharToMultiByte Win32 преобразования для большего количества информации
Таким образом, если Вы работаете над Windows, Вы плохо хотите использовать wchar_t
(если Вы не используете платформу, скрывающую это, как [1 157] GTK + или QT...). Факт - то, что негласно, работы Windows с [1 131] строки, поэтому даже историческим приложениям преобразуют их char
строки в [1 133] при использовании API как [1 134] (низкоуровневая API-функция для установки маркирования на Win32 GUI).
UTF-32 составляет 4 байта на символы, таким образом, существует не очень для добавления, если только, что текст UTF-8 и текст UTF-16 будут всегда использовать меньше или тот же объем памяти, чем текст UTF-32 (и обычно меньше).
, Если существует проблема памяти, то необходимо знать, чем для большинства западных языков, текст UTF-8 будет использовать меньше памяти, чем тот же UTF-16 один.
однако, для других языков (китайский язык, японский язык, и т.д.), используемая память будет или тем же, или немного больше для UTF-8, чем для UTF-16.
, В целом, UTF-16 будет главным образом использовать 2 и иногда 4 байта на символы (если Вы не будете иметь дело с некоторыми тайными глифами языка (Klingon? Волшебный?), в то время как UTF-8 потратит от 1 до 4 байтов.
Видят http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16 для большего количества информации
, Когда я должен использовать станд.:: wstring по станд.:: строка?
На Linux? Почти никогда (В§).
В Windows? Почти всегда (В§).
На межплатформенном коде? Зависит от Вашего инструментария...
(В§): если Вы не используете инструментарий/платформу, говорящий иначе
, Может std::string
содержать весь набор символов ASCII включая специальные символы?
Уведомление: std::string
подходит для содержания 'двоичного' буфера, где std::wstring
не!
На Linux? Да.
В Windows? Только специальные символы, доступные для текущей локали пользователя Windows.
Редактирование (После комментария от [1 160] Johann Gerell ): std::string
будет достаточно для обработки всего char
- базирующиеся строки (каждый char
являющийся числом от 0 до 255). Но:
char
с НЕ являются ASCII. char
от 0 до 127 будет сохранен правильно char
от 128 до 255, будет иметь значение в зависимости от Вашего кодирования (unicode, non-unicode, и т.д.), но оно будет в состоянии содержать все глифы Unicode, пока они кодируются в UTF-8. std::wstring
поддерживаются почти всеми популярными компиляторами C++?
Главным образом, за исключением GCC основывал компиляторы, которые портированы к Windows.
Это работает над моим g ++ 4.3.2 (в соответствии с Linux), и я использовал API Unicode на Win32 начиная с Visual C++ 6.
, Что такое точно широкий символ?
На C/C++, это - тип символов, записанный wchar_t
, который больше, чем простое char
тип символов. Это, как предполагается, используется для вставления символов, индексы которых (как глифы Unicode) больше, чем 255 (или 127, завися...).
Если я понимаю Ваш вопрос, я думаю, что Вам нужно что-то как:
for dup in $(sort -k1,1 -u file.txt | cut -d' ' -f1); do grep -n -- "$dup" file.txt; done
или:
for dup in $(cut -d " " -f1 file.txt | uniq -d); do grep -n -- "$dup" file.txt; done
, где file.txt
Ваш файл, содержащий данные о Вас, интересно.
В выводе Вы будете видеть количество строк и строк, где первое поле найдено два или больше раза.
Это - классическая проблема, которая может быть решена с эти uniq
команда. uniq
может обнаружить дубликат последовательный строки и удалить дубликаты (-u
, --unique
) или сохранить дубликаты только (-d
, --repeated
).
Начиная с упорядочивания дублирующихся строк не важно для Вас, необходимо отсортировать его сначала. Тогда используйте uniq
для печати уникальных строк только:
sort yourfile.txt | uniq -u
существует также -c
опция (--count
), которая печатает количество дубликатов для -d
опция. См. страницу руководства uniq
для деталей.
, Если Вы действительно не заботитесь о частях после первого поля, можно использовать следующую команду для нахождения, делают дубликаты ключа и печатают каждый номер строки для него (добавьте другой | sort -n
, чтобы отсортировать вывод с методической точностью):
cut -d ' ' -f1 .bash_history | nl | sort -k2 | uniq -s8 -D
<час> , Так как Вы хотите видеть дублирующиеся строки (использующий первое поле в качестве ключа), Вы не можете непосредственно использовать uniq
. Проблема, которые делают автоматизацию трудной, - то, что части заголовка варьируются, но программа не может автоматически определить, какой заголовок нужно считать заключительным.
Вот сценарий AWK (сохраните его к [1 116]), который берет Ваш текстовый файл в качестве входа и печатает все дублирующиеся строки, таким образом, можно решить, чтобы удалить. (awk -f script.awk yourfile.txt
)
#!/usr/bin/awk -f
{
# Store the line ([112]) grouped per URL ($1) with line number (NR) as key
lines[$1][NR] = [112];
}
END {
for (url in lines) {
# find lines that have the URL occur multiple times
if (length(lines[url]) > 1) {
for (lineno in lines[url]) {
# Print duplicate line for decision purposes
print lines[url][lineno];
# Alternative: print line number and line
#print lineno, lines[url][lineno];
}
}
}
}
Посмотрите следующий отсортированный file.txt
:
addons.mozilla.org/en-US/firefox/addon/click-to-play-per-element/ ::: C2P per-element
addons.mozilla.org/en-us/firefox/addon/prospector-oneLiner/ ::: OneLiner
askubuntu.com/q/21033 ::: What is the difference between gksudo and gksu?
askubuntu.com/q/21148 ::: openoffice calc sheet tabs (also askubuntu.com/q/138623)
askubuntu.com/q/50540 ::: What is Ubuntu's Definition of a "Registered Application"?
askubuntu.com/q/53762 ::: How to use lm-sensors?
askubuntu.com/q/53762 ::: how-to-use-to-use-lm-sensors
stackoverflow.com/q/4594319 ::: bash - shell replace cr\lf by comma
stackoverflow.com/q/4594319 ::: shell replace cr\lf by comma
wiki.ubuntu.com/ClipboardPersistence ::: ClipboardPersistence
wiki.ubuntu.com/ClipboardPersistence ::: ClipboardPersistence - Ubuntu Wiki
www.youtube.com/watch?v=1olY5Qzmbk8 ::: Create new mime types in Ubuntu
www.youtube.com/watch?v=2hu9JrdSXB8 ::: Change mouse cursor
www.youtube.com/watch?v=Yxfa2fXJ1Wc ::: Mouse cursor size
, поскольку список короток, я вижу (после сортировки), что существует три набора дубликатов.
Затем например, я могу принять решение сохранить:
askubuntu.com/q/53762 ::: How to use lm-sensors?
, а не
askubuntu.com/q/53762 ::: how-to-use-to-use-lm-sensors
, Но для более длинного списка это будет трудно. На основе двух ответов одно предложение uniq
и другое предложение cut
, я нахожу, что эта команда дает мне вывод, который я хотел бы:
$ cut -d " " -f1 file.txt | uniq -d
askubuntu.com/q/53762
stackoverflow.com/q/4594319
wiki.ubuntu.com/ClipboardPersistence
$
cut
. Если Вы делаете работу дедупликации, то номера строки могут быть очень полезными. Для печати всех дубликатов используйте -D
опция вместо -d
.
– Ankit Nigam
16.05.2020, 09:53
for dup in $(cut -d " " -f1 file.txt | uniq -d); do grep -n $dup file.txt; done
как в моем ответе. Это даст Вам лучший предварительный просмотр о том, что Вам интересно.
– James Webster
16.05.2020, 09:53
Если я считал это правильно, все, в чем Вы нуждаетесь, что-то как [1 118]
awk '{print $1}' file | sort | uniq -c |
while read num dupe; do [[ $num > 1 ]] && grep -n -- "$dupe" file; done
, Который распечатает количество строки, которая содержит простофилю и саму строку. Например, использование этого файла:
foo bar baz
http://unix.stackexchange.com/questions/49569/ unique-lines-based-on-the-first-field
bar foo baz
http://unix.stackexchange.com/questions/49569/ Unique lines based on the first field sort, CLI
baz foo bar
http://unix.stackexchange.com/questions/49569/ Unique lines based on the first field
Это произведет этот вывод:
2:http://unix.stackexchange.com/questions/49569/ unique-lines-based-on-the-first-field
4:http://unix.stackexchange.com/questions/49569/ Unique lines based on the first field sort, CLI
6:http://unix.stackexchange.com/questions/49569/ Unique lines based on the first field
Для печати только количества строки Вы могли сделать
awk '{print $1}' file | sort | uniq -c |
while read num dupe; do [[ $num > 1 ]] && grep -n -- "$dupe" file; done | cut -d: -f 1
И распечатать только строку:
awk '{print $1}' file | sort | uniq -c |
while read num dupe; do [[ $num > 1 ]] && grep -n -- "$dupe" file; done | cut -d: -f 2-
<час> Объяснение:
awk
сценарий просто печатает разделенное поле 1-го пространства файла. Используйте $N
для печати поля Nth. sort
виды это и uniq -c
количества случаи каждой строки.
Это тогда передается while
цикл, который сохраняет количество случаев как [1 110] и строка как [1 111] и если $num
будет больше, чем один (таким образом, это дублировано, по крайней мере, однажды), то это будет искать файл ту строку, с помощью [1 113] для печати номера строки. Эти --
говорит grep
, что то, что следует, не является параметром командной строки, полезным для того, когда $dupe
может запуститься с [1 117].
Несомненно самый подробный в списке, могло, вероятно, быть короче:
#!/usr/bin/python3
import collections
file = "file.txt"
def find_duplicates(file):
with open(file, "r") as sourcefile:
data = sourcefile.readlines()
splitlines = [
(index, data[index].split(" ")) for index in range(0, len(data))
]
lineheaders = [item[1][0] for item in splitlines]
dups = [x for x, y in collections.Counter(lineheaders).items() if y > 1]
dupsdata = []
for item in dups:
occurrences = [
splitlines_item[0] for splitlines_item in splitlines\
if splitlines_item[1][0] == item
]
corresponding_lines = [
"["+str(index)+"] "+data[index] for index in occurrences
]
dupsdata.append((occurrences, corresponding_lines))
# printing output
print("found duplicates:\n"+"-"*17)
for index in range(0, len(dups)):
print(dups[index], dupsdata[index][0])
lines = [item for item in dupsdata[index][1]]
for line in lines:
print(line, end = "")
find_duplicates(file)
дает на текстовом файле как:
monkey banana
dog bone
monkey banana peanut
cat mice
dog cowmeat
вывод как:
found duplicates:
-----------------
dog [1, 4]
[1] dog bone
[4] dog cowmeat
monkey [0, 2]
[0] monkey banana
[2] monkey banana peanut
, Как только Вы выбрали строки для удаления:
removelist = [2,1]
def remove_duplicates(file, removelist):
removelist = sorted(removelist, reverse=True)
with open(file, "r") as sourcefile:
data = sourcefile.readlines()
for index in removelist:
data.pop(index)
with open(file, "wt") as sourcefile:
for line in data:
sourcefile.write(line)
remove_duplicates(file, removelist)
Ее то, как я решил его:
file_with_duplicates:
1,a,c
2,a,d
3,a,e <--duplicate
4,a,t
5,b,k <--duplicate
6,b,l
7,b,s
8,b,j
1,b,l
3,a,d <--duplicate
5,b,l <--duplicate
Файл, отсортированный и дедуплицированный столбцами 1 и 2:
sort -t',' -k1,1 -k2,2 -u file_with_duplicates
Файл, отсортированный только по столбцам 1 и 2:
sort -t',' -k1,1 -k2,2 file_with_duplicates
Шоу различие только:
diff <(sort -t',' -k1,1 -k2,2 -u file_with_duplicates) <(sort -t',' -k1,1 -k2,2 file_with_duplicates)
3a4
3,a,d
6a8
5,b,l
cut -d " " -f1 file.txt | uniq -d
дает мне хороший вывод. – Thảo Frederic 16.05.2020, 09:51