명령줄을 사용하여 여러 URL을 도메인 이름으로 변환하는 방법

명령줄을 사용하여 여러 URL을 도메인 이름으로 변환하는 방법

여러 열과 구분 기호로 ","가 포함된 .csv 파일이 있습니다. URL은 첫 번째 열에 있습니다. 다른 열을 제거하지 않고 모든 URL을 도메인으로 변환해야 합니다.

내가 가지고 있는 데이터의 예:

https://www.example.com/dog/url/path/cat.php,column2,$3,4
http://www.unix.random.com/index.html,column2,$3,4
http://example.com/dog/cat.php,column2,$3,4
www.example.com/dog/,column2,$3,4
example.com/url/path/cat/dog,column2,$3,4
https://example.com/,column2,$3,4
https://www.unix.random.com,column2,$3,4
http://www.example.com,column2,$3,4
http://example.com,column2,$3,4
www.random.com,column2,$3,4
example.com/,column2,$3,4 

"/"가 포함되지 않은 다른 열을 건드리지 않고 열 1의 모든 URL을 도메인 이름으로 변환해야 합니다. www 이외의 하위 도메인을 유지해야 합니다.

출력은 다음과 같아야 합니다.

example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
random.com,column2,$3,4
example.com,column2,$3,4 

어떻게 해야 하나요?

답변1

awk를 사용하십시오.

$ awk 'BEGIN{FS=OFS=","} {sub("^([^/:]+://)?(www[.])?","",$1); sub("/.*","",$1)} 1' file
example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
random.com,column2,$3,4
example.com,column2,$3,4

답변2

나는 이것이 효과가 있다고 믿습니다:

sed -E 's#^(.*://)?(www\.)?##; s#^([^,/]+)[^,]*#\1#'

첫 번째 sed 명령( s#^(.*://)?(www\.)?##)은 프로토콜 및 "www"와 일치합니다. 그리고 무엇이든 교체하세요. 두 번째 sed 명령( s#^([^,/]+)[^,]*#\1#)은 첫 번째 슬래시 이전의 모든 항목과 일치한 다음 첫 번째 쉼표 이전의 모든 항목과 일치하고 첫 번째 슬래시 이전의 모든 항목으로 대체하므로 실제로 첫 번째 슬래시에서 첫 번째 쉼표까지 모든 항목이 제거됩니다.

답변3

이는 귀하가 찾고 있는 답변이 아닐 수도 있지만 sed는 운영 체제 간에 일관성이 없을 수 있으며 구문을 읽기도 어렵습니다.

-e이는 아마도 더 나쁠 수도 있지만 또 다른 옵션은 문자열을 평가하는 플래그 와 함께 명령줄에서 Node.js를 사용하는 것입니다 . 단점은 시스템에 Node.js가 설치되어 있어야 한다는 것입니다.

이 코드는 표준 입력에서 파이프로 연결된 모든 항목을 가져오고 수정된 문자열을 표준 출력으로 인쇄합니다.

cat infile.csv | node -e 'const stdin = process.openStdin();
let data = "";
stdin.on("data", chunk => data += chunk);
stdin.on("end", () => {
  console.log(
    data
      .trim()
      .split("\n")
      .filter(Boolean)
      .map((line) => {
        const parts = line.split(",");
        const url = new URL((!/^http(s)?\:\/\//.test(line) ? "https://" : "") + parts.shift());
        return `${url.host.replace(/^www\./,"")},${parts.join(",")}`
      })
      .join("\n"))
});' > outfile.csv

당신은 가질 수 있습니다입력 파일을 덮어쓰는 데 문제가 있습니다.그것이 당신이 하고 싶은 일이라면. 이 문제를 해결하려면 파이프를 사용하는 대신 코드 숨김의 매개변수로 파일 이름을 전달할 수 있습니다.

node -e 'const fs = require("fs");         
const infile = process.argv[1]; const data = fs.readFileSync(infile).toString();
const output = data
  .trim()
  .split("\n")
  .filter(Boolean)
  .map((line) => {
    const parts = line.split(",");
    const url = new URL((!/^http(s)?\:\/\//.test(line) ? "https://" : "") + parts.shift());
    return `${url.host.replace(/^www\./,"")},${parts.join(",")}`
  })
  .join("\n");
fs.writeFileSync(infile, output)' file.csv

답변4

사용행복하다(이전 Perl_6)

raku -pe 's{ (^ <-[/]>* \/\/ )? (w**3 \.)? (<-[/]>*) <-[,]>* } = "$2";'  

[위는 @HatLess의 코드를 번역한 것입니다 sed].

raku -pe 's{ ^ (.* "://" )? (www\.)? } = ""; s{ ^ (<-[,/]>+) <-[,]>* } = "$0";' 

sed[위는 @D_Bear의 코드를 번역한 것입니다].

출력 예(두 경우 모두):

example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
unix.random.com,column2,$3,4
example.com,column2,$3,4
example.com,column2,$3,4
random.com,column2,$3,4
example.com,column2,$3,4 

https://raku.org

관련 정보